{-# LANGUAGE ViewPatterns      #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Text.CSL.Input.Bibtex
-- Copyright   :  (c) John MacFarlane
-- License     :  BSD-style (see LICENSE)
--
-- Maintainer  :  John MacFarlane <fiddlosopher@gmail.com>
-- Stability   :  unstable
-- Portability :  portable
--
-----------------------------------------------------------------------------

module Text.Pandoc.Citeproc.BibTeX
    ( Variant(..)
    , readBibtexString
    , writeBibtexString
    )
    where

import Text.Pandoc.Definition
import Text.Pandoc.Builder as B
import Text.Pandoc.Readers.LaTeX (readLaTeX)
import Text.Pandoc.Extensions (Extension(..), extensionsFromList)
import Text.Pandoc.Options (ReaderOptions(..), WriterOptions)
import Text.Pandoc.Error (PandocError)
import Text.Pandoc.Shared (stringify)
import Text.Pandoc.Writers.LaTeX (writeLaTeX)
import Text.Pandoc.Class (runPure)
import qualified Text.Pandoc.Walk       as Walk
import Citeproc.Types
import Citeproc.Pandoc ()
import Data.List.Split (splitOn)
import Text.Pandoc.Citeproc.Util (toIETF, splitStrWhen)
import Text.Pandoc.Citeproc.Data (biblatexStringMap)
import Text.Pandoc.Citeproc.Name (toName, NameOpts(..), emptyName)
import Data.Default
import           Data.Text              (Text)
import qualified Data.Text              as T
import qualified Data.Map               as Map
import           Data.Maybe
import           Text.Pandoc.Parsing hiding ((<|>), many)
import           Control.Applicative
import           Control.Monad ( guard, MonadPlus(..), void )
import Control.Monad.RWS ( asks, RWST, gets, modify, evalRWST )
import qualified Data.Sequence          as Seq
import           Data.Char              (isAlphaNum, isDigit, isLetter,
                                         isUpper, toLower, toUpper,
                                         isLower, isPunctuation, isSpace)
import           Data.List              (foldl', intercalate, intersperse)
import           Safe                   (readMay)
import           Text.Printf            (printf)
import           Text.DocLayout         (literal, hsep, nest, hang, Doc(..),
                                         braces, ($$), cr)
data Variant = Bibtex | Biblatex
  deriving (Int -> Variant -> ShowS
[Variant] -> ShowS
Variant -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Variant] -> ShowS
$cshowList :: [Variant] -> ShowS
show :: Variant -> String
$cshow :: Variant -> String
showsPrec :: Int -> Variant -> ShowS
$cshowsPrec :: Int -> Variant -> ShowS
Show, Variant -> Variant -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Variant -> Variant -> Bool
$c/= :: Variant -> Variant -> Bool
== :: Variant -> Variant -> Bool
$c== :: Variant -> Variant -> Bool
Eq, Eq Variant
Variant -> Variant -> Bool
Variant -> Variant -> Ordering
Variant -> Variant -> Variant
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Variant -> Variant -> Variant
$cmin :: Variant -> Variant -> Variant
max :: Variant -> Variant -> Variant
$cmax :: Variant -> Variant -> Variant
>= :: Variant -> Variant -> Bool
$c>= :: Variant -> Variant -> Bool
> :: Variant -> Variant -> Bool
$c> :: Variant -> Variant -> Bool
<= :: Variant -> Variant -> Bool
$c<= :: Variant -> Variant -> Bool
< :: Variant -> Variant -> Bool
$c< :: Variant -> Variant -> Bool
compare :: Variant -> Variant -> Ordering
$ccompare :: Variant -> Variant -> Ordering
Ord)

-- | Parse BibTeX or BibLaTeX into a list of 'Reference's.
readBibtexString :: ToSources a
                 => Variant           -- ^ bibtex or biblatex
                 -> Locale            -- ^ Locale
                 -> (Text -> Bool)    -- ^ Filter on citation ids
                 -> a                 -- ^ bibtex/biblatex text
                 -> Either ParseError [Reference Inlines]
readBibtexString :: forall a.
ToSources a =>
Variant
-> Locale
-> (Text -> Bool)
-> a
-> Either ParseError [Reference Inlines]
readBibtexString Variant
variant Locale
locale Text -> Bool
idpred a
contents = do
  case forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> String -> s -> Either ParseError a
runParser (((Variant -> [Item] -> [Item]
resolveCrossRefs Variant
variant forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources (Lang, StringMap) Identity [Item]
bibEntries) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                   forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Locale -> Variant -> Item -> BibParser (Reference Inlines)
itemToReference Locale
locale Variant
variant) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                      forall a. (a -> Bool) -> [a] -> [a]
filter (\Item
item -> Text -> Bool
idpred (Item -> Text
identifier Item
item) Bool -> Bool -> Bool
&&
                                        Item -> Text
entryType Item
item forall a. Eq a => a -> a -> Bool
/= Text
"xdata"))
           (forall a. a -> Maybe a -> a
fromMaybe Lang
defaultLang forall a b. (a -> b) -> a -> b
$ Locale -> Maybe Lang
localeLanguage Locale
locale, forall k a. Map k a
Map.empty)
           (Sources -> String
initialSourceName Sources
sources) Sources
sources of
          Left ParseError
err -> forall a b. a -> Either a b
Left ParseError
err
          Right [Reference Inlines]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return [Reference Inlines]
xs
 where
  sources :: Sources
sources = forall a. ToSources a => a -> Sources
toSources a
contents

-- | Write BibTeX or BibLaTeX given given a 'Reference'.
writeBibtexString :: WriterOptions       -- ^ options (for writing LaTex)
                  -> Variant             -- ^ bibtex or biblatex
                  -> Maybe Lang          -- ^ Language
                  -> Reference Inlines   -- ^ Reference to write
                  -> Doc Text
writeBibtexString :: WriterOptions
-> Variant -> Maybe Lang -> Reference Inlines -> Doc Text
writeBibtexString WriterOptions
opts Variant
variant Maybe Lang
mblang Reference Inlines
ref =
  Doc Text
"@" forall a. Semigroup a => a -> a -> a
<> Doc Text
bibtexType forall a. Semigroup a => a -> a -> a
<> Doc Text
"{" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal (ItemId -> Text
unItemId (forall a. Reference a -> ItemId
referenceId Reference Inlines
ref)) forall a. Semigroup a => a -> a -> a
<> Doc Text
","
  forall a. Doc a -> Doc a -> Doc a
$$ forall a. IsString a => Int -> Doc a -> Doc a
nest Int
2 ([Text] -> Doc Text
renderFields [Text]
fs)
  forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"}" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr

 where
  bibtexType :: Doc Text
bibtexType =
    case forall a. Reference a -> Text
referenceType Reference Inlines
ref of
      Text
"article-magazine"  -> Doc Text
"article"
      Text
"article-newspaper" -> Doc Text
"article"
      Text
"article-journal"   -> Doc Text
"article"
      Text
"book"              -> Doc Text
"book"
      Text
"pamphlet"          -> Doc Text
"booklet"
      Text
"dataset" | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"dataset"
      Text
"webpage" | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"online"
      Text
"chapter"           -> case Text -> Maybe (Val Inlines)
getVariable Text
"editor" of
                                Just Val Inlines
_  -> Doc Text
"incollection"
                                Maybe (Val Inlines)
Nothing -> Doc Text
"inbook"
      Text
"entry-encyclopedia" | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"inreference"
                           | Bool
otherwise -> Doc Text
"inbook"
      Text
"paper-conference"  -> Doc Text
"inproceedings"
      Text
"thesis" -> case Text -> Maybe Text
getVariableAsText Text
"genre" of
                    Just Text
"mathesis" -> Doc Text
"mastersthesis"
                    Maybe Text
_               -> Doc Text
"phdthesis"
      Text
"patent"            | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"patent"
      Text
"report"            | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"report"
                          | Bool
otherwise -> Doc Text
"techreport"
      Text
"speech"            -> Doc Text
"unpublished"
      Text
"manuscript"        -> Doc Text
"unpublished"
      Text
"graphic"           | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"artwork"
      Text
"song"              | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"music"
      Text
"legal_case"        | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"jurisdictionN"
      Text
"legislation"       | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"legislation"
      Text
"treaty"            | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"legal"
      Text
"personal_communication" | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"letter"
      Text
"motion_picture"    | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"movie"
      Text
"review"            | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"review"
      Text
"software"          | Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Biblatex -> Doc Text
"software"
      Text
_                   -> Doc Text
"misc"

  mbSubtype :: Maybe Text
mbSubtype =
    case forall a. Reference a -> Text
referenceType Reference Inlines
ref of
      Text
"article-magazine"  -> forall a. a -> Maybe a
Just Text
"magazine"
      Text
"article-newspaper" -> forall a. a -> Maybe a
Just Text
"newspaper"
      Text
_ -> forall a. Maybe a
Nothing

  fs :: [Text]
fs =
    case Variant
variant of
      Variant
Biblatex ->
           [ Text
"author"
           , Text
"editor"
           , Text
"translator"
           , Text
"publisher"
           , Text
"title"
           , Text
"booktitle"
           , Text
"journal"
           , Text
"series"
           , Text
"edition"
           , Text
"volume"
           , Text
"volumes"
           , Text
"number"
           , Text
"pages"
           , Text
"version"
           , Text
"date"
           , Text
"eventdate"
           , Text
"urldate"
           , Text
"address"
           , Text
"url"
           , Text
"doi"
           , Text
"isbn"
           , Text
"issn"
           , Text
"type"
           , Text
"entrysubtype"
           , Text
"note"
           , Text
"langid"
           , Text
"abstract"
           , Text
"keywords"
           , Text
"annote"
           ]
      Variant
Bibtex ->
           [ Text
"author"
           , Text
"editor"
           , Text
"translator"
           , Text
"publisher"
           , Text
"title"
           , Text
"booktitle"
           , Text
"journal"
           , Text
"series"
           , Text
"edition"
           , Text
"volume"
           , Text
"number"
           , Text
"pages"
           , Text
"year"
           , Text
"month"
           , Text
"address"
           , Text
"type"
           , Text
"note"
           , Text
"annote"
           , Text
"url" -- not officially supported, but supported by
                   -- some styles (#8287)
           ]

  valToInlines :: Val Inlines -> Inlines
valToInlines (TextVal Text
t) = Text -> Inlines
B.text Text
t
  valToInlines (FancyVal Inlines
ils) = Inlines
ils
  valToInlines (NumVal Int
n) = Text -> Inlines
B.text (String -> Text
T.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Int
n)
  valToInlines (NamesVal [Name]
names) =
    forall a. Monoid a => [a] -> a
mconcat forall a b. (a -> b) -> a -> b
$ forall a. a -> [a] -> [a]
intersperse (Inlines
B.space forall a. Semigroup a => a -> a -> a
<> Text -> Inlines
B.text Text
"and" forall a. Semigroup a => a -> a -> a
<> Inlines
B.space)
            forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Name -> Inlines
renderName [Name]
names
  valToInlines (DateVal Date
date) = Text -> Inlines
B.text forall a b. (a -> b) -> a -> b
$
    case Date -> Maybe Text
dateLiteral Date
date of
      Just Text
t  -> Text
t
      Maybe Text
Nothing -> Text -> [Text] -> Text
T.intercalate Text
"/" (forall a b. (a -> b) -> [a] -> [b]
map DateParts -> Text
renderDatePart (Date -> [DateParts]
dateParts Date
date)) forall a. Semigroup a => a -> a -> a
<>
                    (if Date -> Bool
dateCirca Date
date then Text
"~" else forall a. Monoid a => a
mempty)
  valToInlines Val Inlines
SubstitutedVal = forall a. Monoid a => a
mempty

  renderDatePart :: DateParts -> Text
renderDatePart (DateParts [Int]
xs) = Text -> [Text] -> Text
T.intercalate Text
"-" forall a b. (a -> b) -> a -> b
$
                                    forall a b. (a -> b) -> [a] -> [b]
map (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. PrintfType r => String -> r
printf String
"%02d") [Int]
xs

  renderName :: Name -> Inlines
renderName Name
name =
    case Name -> Maybe Text
nameLiteral Name
name of
      Just Text
t  -> Text -> Inlines
B.text Text
t
      Maybe Text
Nothing -> [Maybe Text] -> Inlines
spacedMaybes
                  [ Name -> Maybe Text
nameNonDroppingParticle Name
name
                  , Name -> Maybe Text
nameFamily Name
name
                  , if Name -> Bool
nameCommaSuffix Name
name
                        then (Text
", " forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Maybe Text
nameSuffix Name
name
                        else Name -> Maybe Text
nameSuffix Name
name ]
                  forall a. Semigroup a => a -> a -> a
<>
                  [Maybe Text] -> Inlines
spacedMaybes
                   [ (Text
", " forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> Maybe Text
nameGiven Name
name,
                     Name -> Maybe Text
nameDroppingParticle Name
name ]

  mblang' :: Maybe Lang
mblang' = case Text -> Maybe Text
getVariableAsText Text
"language" of
              Just Text
l  -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const forall a. Maybe a
Nothing) forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> Either String Lang
parseLang Text
l
              Maybe Text
Nothing -> Maybe Lang
mblang

  titlecase :: Inlines -> Inlines
titlecase = case Maybe Lang
mblang' of
                Just Lang
lang | Lang -> Text
langLanguage Lang
lang forall a. Eq a => a -> a -> Bool
== Text
"en"
                                   -> Inlines -> Inlines
titlecase'
                Maybe Lang
Nothing            -> Inlines -> Inlines
titlecase'
                Maybe Lang
_                  ->
                  case Variant
variant of
                    Variant
Bibtex         -> Attr -> Inlines -> Inlines
B.spanWith Attr
nullAttr
                     -- BibTex lacks a language field, so we wrap non-English
                     -- titles in {} to protect case.
                    Variant
Biblatex       -> forall a. a -> a
id

  titlecase' :: Inlines -> Inlines
titlecase' = forall a. CiteprocOutput a => Maybe Lang -> TextCase -> a -> a
addTextCase Maybe Lang
mblang' TextCase
TitleCase forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    (\Inlines
ils -> forall a. [a] -> Many a
B.fromList
               (case forall a. Many a -> [a]
B.toList Inlines
ils of
                  Str Text
t : [Inline]
xs -> Text -> Inline
Str Text
t forall a. a -> [a] -> [a]
: forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk Inline -> Inline
spanAroundCapitalizedWords [Inline]
xs
                  [Inline]
xs         -> forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk Inline -> Inline
spanAroundCapitalizedWords [Inline]
xs))

  -- protect capitalized words when we titlecase
  spanAroundCapitalizedWords :: Inline -> Inline
spanAroundCapitalizedWords (Str Text
t)
    | Bool -> Bool
not ((Char -> Bool) -> Text -> Bool
T.all (\Char
c -> Char -> Bool
isLower Char
c Bool -> Bool -> Bool
|| Bool -> Bool
not (Char -> Bool
isLetter Char
c)) Text
t) =
       Attr -> [Inline] -> Inline
Span (Text
"",[Text
"nocase"],[]) [Text -> Inline
Str Text
t]
  spanAroundCapitalizedWords Inline
x = Inline
x

  spacedMaybes :: [Maybe Text] -> Inlines
spacedMaybes = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse Inlines
B.space forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Inlines
B.text)

  toLaTeX :: Inlines -> Maybe (Doc Text)
toLaTeX Inlines
x =
    case forall a. PandocPure a -> Either PandocError a
runPure (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeLaTeX WriterOptions
opts forall a b. (a -> b) -> a -> b
$ Blocks -> Pandoc
doc (Inlines -> Blocks
B.plain Inlines
x)) of
           Left PandocError
_  -> forall a. Maybe a
Nothing
           Right Text
t -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [Doc a] -> Doc a
hsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. HasChars a => a -> Doc a
literal forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.words Text
t

  renderField :: Text -> Maybe (Doc Text)
  renderField :: Text -> Maybe (Doc Text)
renderField Text
name =
    (((forall a. HasChars a => a -> Doc a
literal Text
name) forall a. Semigroup a => a -> a -> a
<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IsString a => Int -> Doc a -> Doc a -> Doc a
hang Int
2 Doc Text
" = " forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasChars a => Doc a -> Doc a
braces)
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe (Doc Text)
getContentsFor Text
name

  getVariable :: Text -> Maybe (Val Inlines)
getVariable Text
v = forall a.
CiteprocOutput a =>
Variable -> Reference a -> Maybe (Val a)
lookupVariable (Text -> Variable
toVariable Text
v) Reference Inlines
ref

  getVariableAsText :: Text -> Maybe Text
getVariableAsText Text
v = (forall a. Walkable Inline a => a -> Text
stringify forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe (Val Inlines)
getVariable Text
v

  getYear :: Val a -> Maybe (Doc Text)
getYear Val a
val =
    case Val a
val of
       DateVal Date
date ->
         case Date -> Maybe Text
dateLiteral Date
date of
           Just Text
t -> Inlines -> Maybe (Doc Text)
toLaTeX (Text -> Inlines
B.text Text
t)
           Maybe Text
Nothing ->
             case Date -> [DateParts]
dateParts Date
date of
               [DateParts (Int
y1:[Int]
_), DateParts (Int
y2:[Int]
_)] ->
                 forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal (String -> Text
T.pack (forall r. PrintfType r => String -> r
printf String
"%04d" Int
y1) forall a. Semigroup a => a -> a -> a
<> Text
"--" forall a. Semigroup a => a -> a -> a
<>
                        String -> Text
T.pack (forall r. PrintfType r => String -> r
printf String
"%04d" Int
y2))
               [DateParts (Int
y1:[Int]
_)] ->
                 forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal (String -> Text
T.pack (forall r. PrintfType r => String -> r
printf String
"%04d" Int
y1))
               [DateParts]
_ -> forall a. Maybe a
Nothing
       Val a
_ -> forall a. Maybe a
Nothing

  toMonth :: a -> Text
toMonth a
1 = Text
"jan"
  toMonth a
2 = Text
"feb"
  toMonth a
3 = Text
"mar"
  toMonth a
4 = Text
"apr"
  toMonth a
5 = Text
"may"
  toMonth a
6 = Text
"jun"
  toMonth a
7 = Text
"jul"
  toMonth a
8 = Text
"aug"
  toMonth a
9 = Text
"sep"
  toMonth a
10 = Text
"oct"
  toMonth a
11 = Text
"nov"
  toMonth a
12 = Text
"dec"
  toMonth a
x  = String -> Text
T.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show a
x

  getMonth :: Val a -> Maybe (Doc Text)
getMonth Val a
val =
    case Val a
val of
       DateVal Date
date ->
         case Date -> [DateParts]
dateParts Date
date of
           [DateParts (Int
_:Int
m1:[Int]
_), DateParts (Int
_:Int
m2:[Int]
_)] ->
             forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal (forall {a}. (Eq a, Num a, Show a) => a -> Text
toMonth Int
m1 forall a. Semigroup a => a -> a -> a
<> Text
"--" forall a. Semigroup a => a -> a -> a
<> forall {a}. (Eq a, Num a, Show a) => a -> Text
toMonth Int
m2)
           [DateParts (Int
_:Int
m1:[Int]
_)] -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal (forall {a}. (Eq a, Num a, Show a) => a -> Text
toMonth Int
m1)
           [DateParts]
_ -> forall a. Maybe a
Nothing
       Val a
_ -> forall a. Maybe a
Nothing

  getContentsFor :: Text -> Maybe (Doc Text)
  getContentsFor :: Text -> Maybe (Doc Text)
getContentsFor Text
"type" =
    Text -> Maybe Text
getVariableAsText Text
"genre" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
       \case
          Text
"mathesis"  -> forall a. a -> Maybe a
Just Doc Text
"mastersthesis"
          Text
"phdthesis" -> forall a. a -> Maybe a
Just Doc Text
"phdthesis"
          Text
_           -> forall a. Maybe a
Nothing
  getContentsFor Text
"entrysubtype" = forall a. HasChars a => a -> Doc a
literal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
mbSubtype
  getContentsFor Text
"journal"
    | Doc Text
bibtexType forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Doc Text
"article", Doc Text
"periodical", Doc Text
"suppperiodical", Doc Text
"review"]
      = Text -> Maybe (Val Inlines)
getVariable Text
"container-title" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
    | Bool
otherwise = forall a. Maybe a
Nothing
  getContentsFor Text
"booktitle"
    | Doc Text
bibtexType forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
       [Doc Text
"inbook",Doc Text
"incollection",Doc Text
"inproceedings",Doc Text
"inreference",Doc Text
"bookinbook"]
    = (Text -> Maybe (Val Inlines)
getVariable Text
"volume-title" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Maybe (Val Inlines)
getVariable Text
"container-title")
                               forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
    | Bool
otherwise = forall a. Maybe a
Nothing
  getContentsFor Text
"series" = Text -> Maybe (Val Inlines)
getVariable Text
"collection-title"
                               forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"address" = Text -> Maybe (Val Inlines)
getVariable Text
"publisher-place"
                               forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"date"  = Text -> Maybe (Val Inlines)
getVariable Text
"issued" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"eventdate" = Text -> Maybe (Val Inlines)
getVariable Text
"event-date" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"urldate"  = Text -> Maybe (Val Inlines)
getVariable Text
"accessed" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"year"  = Text -> Maybe (Val Inlines)
getVariable Text
"issued" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. Val a -> Maybe (Doc Text)
getYear
  getContentsFor Text
"month"  = Text -> Maybe (Val Inlines)
getVariable Text
"issued" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. Val a -> Maybe (Doc Text)
getMonth
  getContentsFor Text
"pages"  = Text -> Maybe (Val Inlines)
getVariable Text
"page" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"langid"  = Text -> Maybe (Val Inlines)
getVariable Text
"language" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
  getContentsFor Text
"number" = (Text -> Maybe (Val Inlines)
getVariable Text
"number"
                         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Maybe (Val Inlines)
getVariable Text
"collection-number"
                         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Maybe (Val Inlines)
getVariable Text
"issue") forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines

  getContentsFor Text
x = Text -> Maybe (Val Inlines)
getVariable Text
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
    if forall {a}. (Eq a, IsString a) => a -> Bool
isURL Text
x
       then forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasChars a => a -> Doc a
literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val Inlines -> Inlines
valToInlines
       else Inlines -> Maybe (Doc Text)
toLaTeX forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            (if Text
x forall a. Eq a => a -> a -> Bool
== Text
"title"
                then Inlines -> Inlines
titlecase
                else forall a. a -> a
id) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            Val Inlines -> Inlines
valToInlines

  isURL :: a -> Bool
isURL a
x = a
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [a
"url",a
"doi",a
"issn",a
"isbn"]

  renderFields :: [Text] -> Doc Text
renderFields = forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse (Doc Text
"," forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Text -> Maybe (Doc Text)
renderField

defaultLang :: Lang
defaultLang :: Lang
defaultLang = Text
-> Maybe Text
-> Maybe Text
-> [Text]
-> [(Text, [(Text, Text)])]
-> [Text]
-> Lang
Lang Text
"en" forall a. Maybe a
Nothing (forall a. a -> Maybe a
Just Text
"US") [] [] []

-- a map of bibtex "string" macros
type StringMap = Map.Map Text Text

type BibParser = Parsec Sources (Lang, StringMap)

data Item = Item{ Item -> Text
identifier :: Text
                , Item -> SourcePos
sourcePos  :: SourcePos
                , Item -> Text
entryType  :: Text
                , Item -> StringMap
fields     :: Map.Map Text Text
                }
                deriving (Int -> Item -> ShowS
[Item] -> ShowS
Item -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Item] -> ShowS
$cshowList :: [Item] -> ShowS
show :: Item -> String
$cshow :: Item -> String
showsPrec :: Int -> Item -> ShowS
$cshowsPrec :: Int -> Item -> ShowS
Show, Eq Item
Item -> Item -> Bool
Item -> Item -> Ordering
Item -> Item -> Item
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Item -> Item -> Item
$cmin :: Item -> Item -> Item
max :: Item -> Item -> Item
$cmax :: Item -> Item -> Item
>= :: Item -> Item -> Bool
$c>= :: Item -> Item -> Bool
> :: Item -> Item -> Bool
$c> :: Item -> Item -> Bool
<= :: Item -> Item -> Bool
$c<= :: Item -> Item -> Bool
< :: Item -> Item -> Bool
$c< :: Item -> Item -> Bool
compare :: Item -> Item -> Ordering
$ccompare :: Item -> Item -> Ordering
Ord, Item -> Item -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Item -> Item -> Bool
$c/= :: Item -> Item -> Bool
== :: Item -> Item -> Bool
$c== :: Item -> Item -> Bool
Eq)

itemToReference :: Locale -> Variant -> Item -> BibParser (Reference Inlines)
itemToReference :: Locale -> Variant -> Item -> BibParser (Reference Inlines)
itemToReference Locale
locale Variant
variant Item
item = do
  forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition (Item -> SourcePos
sourcePos Item
item)
  forall a. Item -> Bib a -> BibParser a
bib Item
item forall a b. (a -> b) -> a -> b
$ do
    let lang :: Lang
lang = forall a. a -> Maybe a -> a
fromMaybe Lang
defaultLang forall a b. (a -> b) -> a -> b
$ Locale -> Maybe Lang
localeLanguage Locale
locale
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \BibState
st -> BibState
st{ localeLang :: Lang
localeLang = Lang
lang,
                        untitlecase :: Bool
untitlecase = Lang -> Text
langLanguage Lang
lang forall a. Eq a => a -> a -> Bool
== Text
"en" }

    Text
id' <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> Text
identifier
    Maybe Text
otherIds <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"ids")
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    (Text
reftype, Maybe Text
genre) <- Bib (Text, Maybe Text)
getTypeAndGenre
    -- hyphenation:
    let getLangId :: Bib Text
getLangId = do
             Text
langid <- Text -> Text
T.strip forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toLower forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"langid"
             Text
idopts <- Text -> Text
T.strip forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toLower forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                           Text -> Bib Inlines
getField Text
"langidopts" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Text
""
             case (Text
langid, Text
idopts) of
                  (Text
"english",Text
"variant=british")    -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"british"
                  (Text
"english",Text
"variant=american")   -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"american"
                  (Text
"english",Text
"variant=us")         -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"american"
                  (Text
"english",Text
"variant=usmax")      -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"american"
                  (Text
"english",Text
"variant=uk")         -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"british"
                  (Text
"english",Text
"variant=australian") -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"australian"
                  (Text
"english",Text
"variant=newzealand") -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
"newzealand"
                  (Text
x,Text
_)                            -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
x
    Maybe Text
hyphenation <- (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
toIETF forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toLower forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                     (Bib Text
getLangId forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Text
getRawField Text
"hyphenation"))
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \BibState
s -> BibState
s{ untitlecase :: Bool
untitlecase = BibState -> Bool
untitlecase BibState
s Bool -> Bool -> Bool
&&
                                      case Maybe Text
hyphenation of
                                        Just Text
x -> Text
"en-" Text -> Text -> Bool
`T.isPrefixOf` Text
x
                                        Maybe Text
_ -> Bool
True }


    [(Text, Text)]
opts <- (Text -> [(Text, Text)]
parseOptions forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"options") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return []

    Text
et <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> Text
entryType

    -- titles
    let isArticle :: Bool
isArticle = Text
et forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
                     [Text
"article", Text
"periodical", Text
"suppperiodical", Text
"review"]
    let isPeriodical :: Bool
isPeriodical = Text
et forall a. Eq a => a -> a -> Bool
== Text
"periodical"
    let isChapterlike :: Bool
isChapterlike = Text
et forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
           [Text
"inbook",Text
"incollection",Text
"inproceedings",Text
"inreference",Text
"bookinbook"]

    let getFieldMaybe :: Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
f = (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
f) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- names
    let getNameList' :: Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
f = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
         [(Text, Text)] -> Text -> Bib [Name]
getNameList [(Text, Text)]
opts Text
f

    Maybe [Name]
author' <- Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
"author" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe [Name]
containerAuthor' <- Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
"bookauthor" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe [Name]
translator' <- Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
"translator" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Text
editortype <- Text -> Bib Text
getRawField Text
"editortype" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
    Maybe [Name]
editor'' <- Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
"editor" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe [Name]
director'' <- Text -> RWST Item () BibState BibParser (Maybe [Name])
getNameList' Text
"director" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    let (Maybe [Name]
editor', Maybe [Name]
director') = case Text
editortype of
                                    Text
"director" -> (forall a. Maybe a
Nothing, Maybe [Name]
editor'')
                                    Text
_          -> (Maybe [Name]
editor'', Maybe [Name]
director'')
    -- FIXME: add same for editora, editorb, editorc

    -- dates
    Maybe Date
issued' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> RWST Item () BibState BibParser Date
getDate Text
"date" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> RWST Item () BibState BibParser Date
getOldDate forall a. Monoid a => a
mempty)) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
               forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Date
eventDate' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> RWST Item () BibState BibParser Date
getDate Text
"eventdate" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> RWST Item () BibState BibParser Date
getOldDate Text
"event")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                   forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Date
origDate' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> RWST Item () BibState BibParser Date
getDate Text
"origdate" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> RWST Item () BibState BibParser Date
getOldDate Text
"orig")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                   forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Date
accessed' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Text -> RWST Item () BibState BibParser Date
getDate Text
"urldate" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> RWST Item () BibState BibParser Date
getOldDate Text
"url")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- locators
    Maybe Inlines
pages' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"pages"
    Maybe Inlines
volume' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"volume"
    Maybe Inlines
part' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"part"
    Maybe Inlines
volumes' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"volumes"
    Maybe Inlines
pagetotal' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"pagetotal"
    Maybe Inlines
chapter' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"chapter"
    Maybe Inlines
edition' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"edition"
    Maybe Inlines
version' <- Text -> RWST Item () BibState BibParser (Maybe Inlines)
getFieldMaybe Text
"version"
    (Maybe Inlines
number', Maybe Inlines
collectionNumber', Maybe Inlines
issue') <-
       (Text -> Bib Inlines
getField Text
"number" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Inlines
x ->
         if Text
et forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"book",Text
"collection",Text
"proceedings",Text
"reference",
                       Text
"mvbook",Text
"mvcollection",Text
"mvproceedings", Text
"mvreference",
                       Text
"bookinbook",Text
"inbook", Text
"incollection",Text
"inproceedings",
                       Text
"inreference", Text
"suppbook",Text
"suppcollection"]
         then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. a -> Maybe a
Just Inlines
x, forall a. Maybe a
Nothing)
         else if Bool
isArticle
              then (Text -> Bib Inlines
getField Text
"issue" forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Inlines
y ->
                      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. Maybe a
Nothing, forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Char -> [Inlines] -> Inlines
concatWith Char
',' [Inlines
x,Inlines
y]))
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. Maybe a
Nothing, forall a. a -> Maybe a
Just Inlines
x)
              else forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Inlines
x, forall a. Maybe a
Nothing, forall a. Maybe a
Nothing))
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. Maybe a
Nothing, forall a. Maybe a
Nothing)

    -- titles
    Bool
hasMaintitle <- (Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Bib Text
getRawField Text
"maintitle") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

    Maybe Inlines
title' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
              ((forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"issuetitle")
              forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                   forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                   Text -> Bib Inlines
getTitle Text
"maintitle")
              forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getTitle Text
"title")
              forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    Inlines
subtitle' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"issuesubtitle")
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                       forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                       Text -> Bib Inlines
getTitle Text
"mainsubtitle")
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getTitle Text
"subtitle"
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
    Inlines
titleaddon' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                     forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                     Text -> Bib Inlines
getTitle Text
"maintitleaddon")
                    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getTitle Text
"titleaddon"
                    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty

    Maybe Inlines
volumeTitle' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                    ((forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                      forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                      Text -> Bib Inlines
getTitle Text
"title")
                     forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          Text -> Bib Inlines
getTitle Text
"booktitle"))
                    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Inlines
volumeSubtitle' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                        forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                        Text -> Bib Inlines
getTitle Text
"subtitle")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                            forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                            Text -> Bib Inlines
getTitle Text
"booksubtitle")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
    Inlines
volumeTitleAddon' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                          Text -> Bib Inlines
getTitle Text
"titleaddon")
                         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
hasMaintitle forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              Text -> Bib Inlines
getTitle Text
"booktitleaddon")
                         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty

    Maybe Inlines
containerTitle' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                       ((forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getPeriodicalTitle Text
"title")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"maintitle")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"booktitle")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getPeriodicalTitle Text
"journaltitle"
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getPeriodicalTitle Text
"journal")
                       forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Inlines
containerSubtitle' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getPeriodicalTitle Text
"subtitle")
                          forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"mainsubtitle")
                          forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Bib Inlines
getTitle Text
"booksubtitle")
                          forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getPeriodicalTitle Text
"journalsubtitle"
                          forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
    Inlines
containerTitleAddon' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                             Text -> Bib Inlines
getPeriodicalTitle Text
"titleaddon")
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                                 Text -> Bib Inlines
getTitle Text
"maintitleaddon")
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isChapterlike forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                                 Text -> Bib Inlines
getTitle Text
"booktitleaddon")
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
    Maybe Inlines
containerTitleShort' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                            ((forall (f :: * -> *). Alternative f => Bool -> f ()
guard Bool
isPeriodical forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
hasMaintitle) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              Text -> Bib Inlines
getField Text
"shorttitle")
                            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getPeriodicalTitle Text
"shortjournal")
                           forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- change numerical series title to e.g. 'series 3'
    let fixSeriesTitle :: [Inline] -> [Inline]
fixSeriesTitle [Str Text
xs] | Text -> Bool
isNumber Text
xs =
          [Text -> Inline
Str (Locale -> Text -> Text
ordinalize Locale
locale Text
xs), Inline
Space, Text -> Inline
Str (Lang -> Text -> Text
resolveKey' Lang
lang Text
"jourser")]
        fixSeriesTitle [Inline]
xs = [Inline]
xs

    Maybe Inlines
seriesTitle' <- (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Many a
B.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> [Inline]
fixSeriesTitle forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Many a -> [a]
B.toList
                       forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getTitle Text
"series") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                    forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
shortTitle' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not Bool
hasMaintitle Bool -> Bool -> Bool
|| Bool
isChapterlike) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              Text -> Bib Inlines
getTitle Text
"shorttitle"))
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (if (Inlines
subtitle' forall a. Eq a => a -> a -> Bool
/= forall a. Monoid a => a
mempty Bool -> Bool -> Bool
|| Inlines
titleaddon' forall a. Eq a => a -> a -> Bool
/= forall a. Monoid a => a
mempty) Bool -> Bool -> Bool
&&
                          Bool -> Bool
not Bool
hasMaintitle
                          then Bool -> Text -> RWST Item () BibState BibParser (Maybe Inlines)
getShortTitle Bool
False Text
"title"
                          else Bool -> Text -> RWST Item () BibState BibParser (Maybe Inlines)
getShortTitle Bool
True  Text
"title")
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    Maybe Inlines
eventTitle' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getTitle Text
"eventtitle" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
origTitle' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getTitle Text
"origtitle" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- publisher
    [Maybe Inlines]
pubfields <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\Text
f -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap`
                         (if Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Bibtex Bool -> Bool -> Bool
|| Text
f forall a. Eq a => a -> a -> Bool
== Text
"howpublished"
                          then Text -> Bib Inlines
getField Text
f
                          else Text -> Bib Inlines
getLiteralList' Text
f)
                        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)
           [Text
"school",Text
"institution",Text
"organization", Text
"howpublished",Text
"publisher"]
    let publisher' :: Maybe Inlines
publisher' = case forall a. [Maybe a] -> [a]
catMaybes [Maybe Inlines]
pubfields of
                       [] -> forall a. Maybe a
Nothing
                       [Inlines]
xs -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Char -> [Inlines] -> Inlines
concatWith Char
';' [Inlines]
xs
    Maybe Inlines
origpublisher' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"origpublisher") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- places
    Maybe Inlines
venue' <- (forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"venue") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
address' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                  (if Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Bibtex
                      then Text -> Bib Inlines
getField Text
"address"
                      else Text -> Bib Inlines
getLiteralList' Text
"address"
                         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text
et forall a. Eq a => a -> a -> Bool
/= Text
"patent") forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                              Text -> Bib Inlines
getLiteralList' Text
"location"))
                forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
origLocation' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                  (if Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Bibtex
                      then Text -> Bib Inlines
getField Text
"origlocation"
                      else Text -> Bib Inlines
getLiteralList' Text
"origlocation")
                    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
jurisdiction' <- if Text
reftype forall a. Eq a => a -> a -> Bool
== Text
"patent"
                     then forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                        (Char -> [Inlines] -> Inlines
concatWith Char
';' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (Lang -> Inlines -> Inlines
resolveKey Lang
lang) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                             Text -> Bib [Inlines]
getLiteralList Text
"location") forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
                     else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- url, doi, isbn, etc.:
    -- note that with eprinttype = arxiv, we take eprint to be a partial url
    -- archivePrefix is an alias for eprinttype
    Maybe Text
url' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Text
et forall a. Eq a => a -> a -> Bool
== Text
"online" Bool -> Bool -> Bool
|| forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"url" [(Text, Text)]
opts forall a. Eq a => a -> a -> Bool
/= forall a. a -> Maybe a
Just Text
"false")
             forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"url")
         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (do Text
etype <- Text -> Bib Text
getRawField Text
"eprinttype"
                 Text
eprint <- Text -> Bib Text
getRawField Text
"eprint"
                 let baseUrl :: Text
baseUrl =
                       case Text -> Text
T.toLower Text
etype of
                         Text
"arxiv"       -> Text
"https://arxiv.org/abs/"
                         Text
"jstor"       -> Text
"https://www.jstor.org/stable/"
                         Text
"pubmed"      -> Text
"https://www.ncbi.nlm.nih.gov/pubmed/"
                         Text
"googlebooks" -> Text
"https://books.google.com?id="
                         Text
_             -> Text
""
                 if Text -> Bool
T.null Text
baseUrl
                    then forall (m :: * -> *) a. MonadPlus m => m a
mzero
                    else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text
baseUrl forall a. Semigroup a => a -> a -> a
<> Text
eprint)
         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
doi' <- (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"doi" [(Text, Text)]
opts forall a. Eq a => a -> a -> Bool
/= forall a. a -> Maybe a
Just Text
"false") forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
             forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"doi")
           forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
isbn' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"isbn" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
issn' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"issn" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
pmid' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField  Text
"pmid" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
pmcid' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"pmcid" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Text
callNumber' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"library" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

    -- notes
    Maybe Inlines
annotation' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                   (Text -> Bib Inlines
getField Text
"annotation" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Inlines
getField Text
"annote")
                     forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
abstract' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"abstract" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
keywords' <- forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"keywords" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
note' <- if Text
et forall a. Eq a => a -> a -> Bool
== Text
"periodical"
             then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
             else forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"note" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
addendum' <- if Variant
variant forall a. Eq a => a -> a -> Bool
== Variant
Bibtex
                    then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
                    else forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"addendum"
                 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    Maybe Inlines
pubstate' <- (  (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lang -> Inlines -> Inlines
resolveKey Lang
lang forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField Text
"pubstate")
                  forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> case Date -> Maybe Text
dateLiteral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Date
issued' of
                           Just (Just Text
"forthcoming") ->
                             forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> Inlines
B.str Text
"forthcoming"
                           Maybe (Maybe Text)
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
                   )




    let addField :: (k, Maybe a) -> Map k a -> Map k a
addField (k
_, Maybe a
Nothing) = forall a. a -> a
id
        addField (k
f, Just a
x)  = forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert k
f a
x
    let vars :: Map Variable (Val Inlines)
vars = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {k} {a}. Ord k => (k, Maybe a) -> Map k a -> Map k a
addField forall a. Monoid a => a
mempty
                [ (Variable
"other-ids", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
otherIds)
                , (Variable
"genre", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
genre)
                , (Variable
"language", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
hyphenation)
                -- dates
                , (Variable
"accessed", forall a. Date -> Val a
DateVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Date
accessed')
                , (Variable
"event-date", forall a. Date -> Val a
DateVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Date
eventDate')
                , (Variable
"issued", forall a. Date -> Val a
DateVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Date
issued')
                , (Variable
"original-date", forall a. Date -> Val a
DateVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Date
origDate')
                -- names
                , (Variable
"author", forall a. [Name] -> Val a
NamesVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Name]
author')
                , (Variable
"editor", forall a. [Name] -> Val a
NamesVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Name]
editor')
                , (Variable
"translator", forall a. [Name] -> Val a
NamesVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Name]
translator')
                , (Variable
"director", forall a. [Name] -> Val a
NamesVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Name]
director')
                , (Variable
"container-author", forall a. [Name] -> Val a
NamesVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Name]
containerAuthor')
                -- locators
                , (Variable
"page", forall a. a -> Val a
FancyVal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk Inline -> Inline
convertEnDash forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
pages')
                , (Variable
"number-of-pages", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
pagetotal')
                , (Variable
"volume", case (Maybe Inlines
volume', Maybe Inlines
part') of
                               (Maybe Inlines
Nothing, Maybe Inlines
Nothing) -> forall a. Maybe a
Nothing
                               (Just Inlines
v, Maybe Inlines
Nothing) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal Inlines
v
                               (Maybe Inlines
Nothing, Just Inlines
p) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal Inlines
p
                               (Just Inlines
v, Just Inlines
p)  ->
                                 forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal forall a b. (a -> b) -> a -> b
$ Inlines
v forall a. Semigroup a => a -> a -> a
<> Text -> Inlines
B.str Text
"." forall a. Semigroup a => a -> a -> a
<> Inlines
p)
                , (Variable
"number-of-volumes", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
volumes')
                , (Variable
"chapter-number", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
chapter')
                , (Variable
"edition", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
edition')
                , (Variable
"version", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
version')
                , (Variable
"number", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
number')
                , (Variable
"collection-number", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
collectionNumber')
                , (Variable
"issue", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
issue')
                -- title
                , (Variable
"original-title", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
origTitle')
                , (Variable
"event", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
eventTitle')
                , (Variable
"title", case Maybe Inlines
title' of
                              Just Inlines
t -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal forall a b. (a -> b) -> a -> b
$
                                         Char -> [Inlines] -> Inlines
concatWith Char
'.' [
                                             Char -> [Inlines] -> Inlines
concatWith Char
':' [Inlines
t, Inlines
subtitle']
                                           , Inlines
titleaddon' ]
                              Maybe Inlines
Nothing -> forall a. Maybe a
Nothing)
                , (Variable
"volume-title",
                            case Maybe Inlines
volumeTitle' of
                              Just Inlines
t -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal forall a b. (a -> b) -> a -> b
$
                                         Char -> [Inlines] -> Inlines
concatWith Char
'.' [
                                             Char -> [Inlines] -> Inlines
concatWith Char
':' [Inlines
t, Inlines
volumeSubtitle']
                                           , Inlines
volumeTitleAddon' ]
                              Maybe Inlines
Nothing -> forall a. Maybe a
Nothing)
                , (Variable
"container-title",
                            case Maybe Inlines
containerTitle' of
                              Just Inlines
t -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal forall a b. (a -> b) -> a -> b
$
                                         Char -> [Inlines] -> Inlines
concatWith Char
'.' [
                                             Char -> [Inlines] -> Inlines
concatWith Char
':' [Inlines
t,
                                               Inlines
containerSubtitle']
                                           , Inlines
containerTitleAddon' ]
                              Maybe Inlines
Nothing -> forall a. Maybe a
Nothing)
                , (Variable
"container-title-short", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
containerTitleShort')
                , (Variable
"collection-title", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
seriesTitle')
                , (Variable
"title-short", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
shortTitle')
                -- publisher
                , (Variable
"publisher", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
publisher')
                , (Variable
"original-publisher", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
origpublisher')
                -- places
                , (Variable
"jurisdiction", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
jurisdiction')
                , (Variable
"event-place",  forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
venue')
                , (Variable
"publisher-place", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
address')
                , (Variable
"original-publisher-place", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
origLocation')
                -- urls
                , (Variable
"url", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
url')
                , (Variable
"doi", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
doi')
                , (Variable
"isbn", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
isbn')
                , (Variable
"issn", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
issn')
                , (Variable
"pmcid", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
pmcid')
                , (Variable
"pmid", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
pmid')
                , (Variable
"call-number", forall a. Text -> Val a
TextVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
callNumber')
                -- notes
                , (Variable
"note", case forall a. [Maybe a] -> [a]
catMaybes [Maybe Inlines
note', Maybe Inlines
addendum'] of
                             [] -> forall a. Maybe a
Nothing
                             [Inlines]
xs -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Val a
FancyVal forall a b. (a -> b) -> a -> b
$ Char -> [Inlines] -> Inlines
concatWith Char
'.' [Inlines]
xs)
                , (Variable
"annote", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
annotation')
                , (Variable
"abstract", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
abstract')
                , (Variable
"keyword", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
keywords')
                , (Variable
"status", forall a. a -> Val a
FancyVal forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Inlines
pubstate')
                ]
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Reference
      { referenceId :: ItemId
referenceId             = Text -> ItemId
ItemId Text
id'
      , referenceType :: Text
referenceType           = Text
reftype
      , referenceDisambiguation :: Maybe DisambiguationData
referenceDisambiguation = forall a. Maybe a
Nothing
      , referenceVariables :: Map Variable (Val Inlines)
referenceVariables      = Map Variable (Val Inlines)
vars }


bib :: Item -> Bib a -> BibParser a
bib :: forall a. Item -> Bib a -> BibParser a
bib Item
entry Bib a
m = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) r w s a.
Monad m =>
RWST r w s m a -> r -> s -> m (a, w)
evalRWST Bib a
m Item
entry (Bool -> Lang -> BibState
BibState Bool
True Lang
defaultLang)

resolveCrossRefs :: Variant -> [Item] -> [Item]
resolveCrossRefs :: Variant -> [Item] -> [Item]
resolveCrossRefs Variant
variant [Item]
entries =
  forall a b. (a -> b) -> [a] -> [b]
map (Variant -> [Item] -> Item -> Item
resolveCrossRef Variant
variant [Item]
entries) [Item]
entries

resolveCrossRef :: Variant -> [Item] -> Item -> Item
resolveCrossRef :: Variant -> [Item] -> Item -> Item
resolveCrossRef Variant
variant [Item]
entries Item
entry =
  forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
Map.foldrWithKey forall {a}. (Eq a, IsString a) => a -> Text -> Item -> Item
go Item
entry (Item -> StringMap
fields Item
entry)
  where go :: a -> Text -> Item -> Item
go a
key Text
val Item
entry' =
          if a
key forall a. Eq a => a -> a -> Bool
== a
"crossref" Bool -> Bool -> Bool
|| a
key forall a. Eq a => a -> a -> Bool
== a
"xdata"
          then Item
entry'{ fields :: StringMap
fields = Item -> StringMap
fields Item
entry' forall a. Semigroup a => a -> a -> a
<>
                          forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (Variant -> Item -> [Item] -> Text -> [(Text, Text)]
getXrefFields Variant
variant
                                        Item
entry [Item]
entries Text
val) }
          else Item
entry'

getXrefFields :: Variant -> Item -> [Item] -> Text -> [(Text, Text)]
getXrefFields :: Variant -> Item -> [Item] -> Text -> [(Text, Text)]
getXrefFields Variant
variant Item
baseEntry [Item]
entries Text
keys = do
  let keys' :: [Text]
keys' = Text -> [Text]
splitKeys Text
keys
  Item
xrefEntry <- [Item
e | Item
e <- [Item]
entries, Item -> Text
identifier Item
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
keys']
  (Text
k, Text
v) <- forall k a. Map k a -> [(k, a)]
Map.toList forall a b. (a -> b) -> a -> b
$ Item -> StringMap
fields Item
xrefEntry
  if Text
k forall a. Eq a => a -> a -> Bool
== Text
"crossref" Bool -> Bool -> Bool
|| Text
k forall a. Eq a => a -> a -> Bool
== Text
"xdata"
     then do
       [(Text, Text)]
xs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Variant -> Item -> [Item] -> Text -> [(Text, Text)]
getXrefFields Variant
variant Item
baseEntry [Item]
entries)
                   (Text -> [Text]
splitKeys Text
v)
       (Text
x, Text
y) <- [(Text, Text)]
xs
       forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall a. Maybe a -> Bool
isNothing forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
x forall a b. (a -> b) -> a -> b
$ Item -> StringMap
fields Item
xrefEntry
       forall (m :: * -> *) a. Monad m => a -> m a
return (Text
x, Text
y)
     else do
       Text
k' <- case Variant
variant of
               Variant
Bibtex -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
k
               Variant
Biblatex -> Text -> Text -> Text -> [Text]
transformKey
                            (Item -> Text
entryType Item
xrefEntry) (Item -> Text
entryType Item
baseEntry) Text
k
       forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ forall a. Maybe a -> Bool
isNothing forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
k' forall a b. (a -> b) -> a -> b
$ Item -> StringMap
fields Item
baseEntry
       forall (m :: * -> *) a. Monad m => a -> m a
return (Text
k',Text
v)



data BibState = BibState{
           BibState -> Bool
untitlecase    :: Bool
         , BibState -> Lang
localeLang     :: Lang
         }

type Bib = RWST Item () BibState BibParser

blocksToInlines :: [Block] -> Inlines
blocksToInlines :: [Block] -> Inlines
blocksToInlines [Block]
bs =
  case [Block]
bs of
       [Plain [Inline]
xs] -> forall a. [a] -> Many a
B.fromList [Inline]
xs
       [Para  [Inline]
xs] -> forall a. [a] -> Many a
B.fromList [Inline]
xs
       [Block]
_          -> forall a. [a] -> Many a
B.fromList forall a b. (a -> b) -> a -> b
$ forall a b c. (Walkable a b, Monoid c) => (a -> c) -> b -> c
Walk.query (forall a. a -> [a] -> [a]
:[]) [Block]
bs

adjustSpans :: Lang -> Inline -> Inline
adjustSpans :: Lang -> Inline -> Inline
adjustSpans Lang
lang (Span (Text
"",[],[(Text
"bibstring",Text
s)]) [Inline]
_) = Text -> Inline
Str forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Text
resolveKey' Lang
lang Text
s
adjustSpans Lang
_ Inline
SoftBreak = Inline
Space
adjustSpans Lang
_ Inline
x = Inline
x

latex' :: Text -> Bib [Block]
latex' :: Text -> Bib [Block]
latex' Text
t = do
  Lang
lang <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets BibState -> Lang
localeLang
  case Lang -> Text -> Either PandocError [Block]
parseLaTeX Lang
lang Text
t of
    Left PandocError
_   -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
    Right [Block]
bs -> forall (m :: * -> *) a. Monad m => a -> m a
return [Block]
bs

parseLaTeX :: Lang -> Text -> Either PandocError [Block]
parseLaTeX :: Lang -> Text -> Either PandocError [Block]
parseLaTeX Lang
lang Text
t =
  case forall a. PandocPure a -> Either PandocError a
runPure (forall (m :: * -> *) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> a -> m Pandoc
readLaTeX
                forall a. Default a => a
def{ readerExtensions :: Extensions
readerExtensions =
                      [Extension] -> Extensions
extensionsFromList [Extension
Ext_raw_tex, Extension
Ext_smart] } Text
t) of
    Left PandocError
e              -> forall a b. a -> Either a b
Left PandocError
e
    Right (Pandoc Meta
_ [Block]
bs) -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk (Lang -> Inline -> Inline
adjustSpans Lang
lang) [Block]
bs

latex :: Text -> Bib Inlines
latex :: Text -> Bib Inlines
latex = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Block] -> Inlines
blocksToInlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bib [Block]
latex' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip

bibEntries :: BibParser [Item]
bibEntries :: ParsecT Sources (Lang, StringMap) Identity [Item]
bibEntries = do
  forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Sources (Lang, StringMap) Identity ()
nonEntry
  forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (ParsecT Sources (Lang, StringMap) Identity Item
bibItem forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Sources (Lang, StringMap) Identity ()
nonEntry)
 where nonEntry :: ParsecT Sources (Lang, StringMap) Identity ()
nonEntry = ParsecT Sources (Lang, StringMap) Identity ()
bibSkip forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                  ParsecT Sources (Lang, StringMap) Identity ()
comment forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                  forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'@' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                       (ParsecT Sources (Lang, StringMap) Identity ()
bibComment forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Sources (Lang, StringMap) Identity ()
bibPreamble forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Sources (Lang, StringMap) Identity ()
bibString))

bibSkip :: BibParser ()
bibSkip :: ParsecT Sources (Lang, StringMap) Identity ()
bibSkip = forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (\Char
c -> Char
c forall a. Eq a => a -> a -> Bool
/=Char
'@' Bool -> Bool -> Bool
&& Char
c forall a. Eq a => a -> a -> Bool
/=Char
'%'))

comment :: BibParser ()
comment :: ParsecT Sources (Lang, StringMap) Identity ()
comment = forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'%' forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine

bibComment :: BibParser ()
bibComment :: ParsecT Sources (Lang, StringMap) Identity ()
bibComment = do
  Text -> BibParser Text
cistring Text
"comment"
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (f :: * -> *) a. Functor f => f a -> f ()
void BibParser Text
inBraces forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Sources (Lang, StringMap) Identity ()
bibSkip forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ()

bibPreamble :: BibParser ()
bibPreamble :: ParsecT Sources (Lang, StringMap) Identity ()
bibPreamble = do
  Text -> BibParser Text
cistring Text
"preamble"
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (f :: * -> *) a. Functor f => f a -> f ()
void BibParser Text
inBraces

bibString :: BibParser ()
bibString :: ParsecT Sources (Lang, StringMap) Identity ()
bibString = do
  Text -> BibParser Text
cistring Text
"string"
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'{'
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  (Text
k,Text
v) <- BibParser (Text, Text)
entField
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'}'
  forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState (\(Lang
l,StringMap
m) -> (Lang
l, forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Text
k Text
v StringMap
m))
  forall (m :: * -> *) a. Monad m => a -> m a
return ()

take1WhileP :: Monad m => (Char -> Bool) -> ParsecT Sources u m Text
take1WhileP :: forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP Char -> Bool
f = String -> Text
T.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
f)

inBraces :: BibParser Text
inBraces :: BibParser Text
inBraces = do
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'{'
  [Text]
res <- forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill
         (  forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP (\Char
c -> Char
c forall a. Eq a => a -> a -> Bool
/= Char
'{' Bool -> Bool -> Bool
&& Char
c forall a. Eq a => a -> a -> Bool
/= Char
'}' Bool -> Bool -> Bool
&& Char
c forall a. Eq a => a -> a -> Bool
/= Char
'\\')
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\\' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Text -> Text
T.cons Char
'\\' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
T.singleton forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar)
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> Text
braced forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BibParser Text
inBraces)
         ) (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'}')
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat [Text]
res

braced :: Text -> Text
braced :: Text -> Text
braced = Char -> Text -> Text
T.cons Char
'{' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Char -> Text
T.snoc Char
'}'

inQuotes :: BibParser Text
inQuotes :: BibParser Text
inQuotes = do
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'"'
  [Text] -> Text
T.concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill
             ( forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP (\Char
c -> Char
c forall a. Eq a => a -> a -> Bool
/= Char
'{' Bool -> Bool -> Bool
&& Char
c forall a. Eq a => a -> a -> Bool
/= Char
'"' Bool -> Bool -> Bool
&& Char
c forall a. Eq a => a -> a -> Bool
/= Char
'\\')
               forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\\' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Text -> Text
T.cons Char
'\\' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
T.singleton forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar)
               forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Text
braced forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BibParser Text
inBraces
            ) (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'"')

fieldName :: BibParser Text
fieldName :: BibParser Text
fieldName = Text -> Text
resolveAlias forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toLower
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP (\Char
c ->
         Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
':' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'+')

isBibtexKeyChar :: Char -> Bool
isBibtexKeyChar :: Char -> Bool
isBibtexKeyChar Char
c =
  Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (String
".:;?!`'()$/*@_+=-[]*&" :: [Char])

spaces' :: BibParser ()
spaces' :: ParsecT Sources (Lang, StringMap) Identity ()
spaces' = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isSpace) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Sources (Lang, StringMap) Identity ()
comment)

bibItem :: BibParser Item
bibItem :: ParsecT Sources (Lang, StringMap) Identity Item
bibItem = do
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'@'
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  Text
enttype <- Text -> Text
T.toLower forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP Char -> Bool
isLetter
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'{'
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  Text
entid <- forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP Char -> Bool
isBibtexKeyChar
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
','
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  [(Text, Text)]
entfields <- BibParser (Text, Text)
entField forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`sepEndBy` (forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
',' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources (Lang, StringMap) Identity ()
spaces')
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'}'
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> Text -> StringMap -> Item
Item Text
entid SourcePos
pos Text
enttype (forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Text, Text)]
entfields)

entField :: BibParser (Text, Text)
entField :: BibParser (Text, Text)
entField = do
  Text
k <- BibParser Text
fieldName
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'='
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  [Text]
vs <- (BibParser Text
expandString forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> BibParser Text
inQuotes forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> BibParser Text
inBraces forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> BibParser Text
rawWord) forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`sepBy`
            forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources (Lang, StringMap) Identity ()
spaces' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'#' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources (Lang, StringMap) Identity ()
spaces')
  ParsecT Sources (Lang, StringMap) Identity ()
spaces'
  forall (m :: * -> *) a. Monad m => a -> m a
return (Text
k, [Text] -> Text
T.concat [Text]
vs)

resolveAlias :: Text -> Text
resolveAlias :: Text -> Text
resolveAlias Text
"archiveprefix" = Text
"eprinttype"
resolveAlias Text
"primaryclass" = Text
"eprintclass"
resolveAlias Text
s = Text
s

rawWord :: BibParser Text
rawWord :: BibParser Text
rawWord = forall (m :: * -> *) u.
Monad m =>
(Char -> Bool) -> ParsecT Sources u m Text
take1WhileP Char -> Bool
isAlphaNum

expandString :: BibParser Text
expandString :: BibParser Text
expandString = do
  Text
k <- BibParser Text
fieldName
  (Lang
lang, StringMap
strs) <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
k StringMap
strs of
       Just Text
v  -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
v
       Maybe Text
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Text
resolveKey' Lang
lang Text
k

cistring :: Text -> BibParser Text
cistring :: Text -> BibParser Text
cistring Text
s = forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall {m :: * -> *} {s} {u}.
(Stream s m Char, UpdateSourcePos s Char) =>
Text -> ParsecT s u m Text
go Text
s)
 where go :: Text -> ParsecT s u m Text
go Text
t = case Text -> Maybe (Char, Text)
T.uncons Text
t of
         Maybe (Char, Text)
Nothing     -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
""
         Just (Char
c,Text
cs) -> do
           Char
x <- forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char (Char -> Char
toLower Char
c) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char (Char -> Char
toUpper Char
c)
           Text
xs <- Text -> ParsecT s u m Text
go Text
cs
           forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> Text -> Text
T.cons Char
x Text
xs)

splitKeys :: Text -> [Text]
splitKeys :: Text -> [Text]
splitKeys = forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> [Text]
T.split (\Char
c -> Char
c forall a. Eq a => a -> a -> Bool
== Char
' ' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
',')

-- Biblatex Localization Keys (see Biblatex manual)
-- Currently we only map a subset likely to be used in Biblatex *databases*
-- (in fields such as `type`, and via `\bibstring{}` commands).

parseMonth :: Text -> Maybe Int
parseMonth :: Text -> Maybe Int
parseMonth Text
s =
  case Text -> Text
T.toLower Text
s of
         Text
"jan" -> forall a. a -> Maybe a
Just Int
1
         Text
"feb" -> forall a. a -> Maybe a
Just Int
2
         Text
"mar" -> forall a. a -> Maybe a
Just Int
3
         Text
"apr" -> forall a. a -> Maybe a
Just Int
4
         Text
"may" -> forall a. a -> Maybe a
Just Int
5
         Text
"jun" -> forall a. a -> Maybe a
Just Int
6
         Text
"jul" -> forall a. a -> Maybe a
Just Int
7
         Text
"aug" -> forall a. a -> Maybe a
Just Int
8
         Text
"sep" -> forall a. a -> Maybe a
Just Int
9
         Text
"oct" -> forall a. a -> Maybe a
Just Int
10
         Text
"nov" -> forall a. a -> Maybe a
Just Int
11
         Text
"dec" -> forall a. a -> Maybe a
Just Int
12
         Text
_     -> forall a. Read a => String -> Maybe a
readMay (Text -> String
T.unpack Text
s)

notFound :: Text -> Bib a
notFound :: forall a. Text -> Bib a
notFound Text
f = forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
f forall a. [a] -> [a] -> [a]
++ String
" not found"

getField :: Text -> Bib Inlines
getField :: Text -> Bib Inlines
getField Text
f = do
  StringMap
fs <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> StringMap
fields
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
f StringMap
fs of
       Just Text
x  -> Text -> Bib Inlines
latex Text
x
       Maybe Text
Nothing -> forall a. Text -> Bib a
notFound Text
f


getPeriodicalTitle :: Text -> Bib Inlines
getPeriodicalTitle :: Text -> Bib Inlines
getPeriodicalTitle Text
f = do
  Inlines
ils <- Text -> Bib Inlines
getField Text
f
  forall (m :: * -> *) a. Monad m => a -> m a
return Inlines
ils

protectCase :: (Inlines -> Inlines) -> (Inlines -> Inlines)
protectCase :: (Inlines -> Inlines) -> Inlines -> Inlines
protectCase Inlines -> Inlines
f = forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk Inline -> Inline
unprotect forall b c a. (b -> c) -> (a -> b) -> a -> c
. Inlines -> Inlines
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Walkable a b => (a -> a) -> b -> b
Walk.walk Inline -> Inline
protect
 where
  protect :: Inline -> Inline
protect (Span (Text
"",[],[]) [Inline]
xs) = Attr -> [Inline] -> Inline
Span (Text
"",[Text
"nocase"],[]) [Inline]
xs
  protect  Inline
x = Inline
x
  unprotect :: Inline -> Inline
unprotect (Span (Text
"",[Text
"nocase"],[]) [Inline]
xs)
    | [Inline] -> Bool
hasLowercaseWord [Inline]
xs = Attr -> [Inline] -> Inline
Span (Text
"",[Text
"nocase"],[]) [Inline]
xs
    | Bool
otherwise           = Attr -> [Inline] -> Inline
Span (Text
"",[],[]) [Inline]
xs
  unprotect Inline
x = Inline
x
  hasLowercaseWord :: [Inline] -> Bool
hasLowercaseWord = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Inline -> Bool
startsWithLowercase forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> [Inline] -> [Inline]
splitStrWhen Char -> Bool
isPunctuation
  startsWithLowercase :: Inline -> Bool
startsWithLowercase (Str (Text -> Maybe (Char, Text)
T.uncons -> Just (Char
x,Text
_))) = Char -> Bool
isLower Char
x
  startsWithLowercase Inline
_           = Bool
False

unTitlecase :: Maybe Lang -> Inlines -> Inlines
unTitlecase :: Maybe Lang -> Inlines -> Inlines
unTitlecase Maybe Lang
mblang = (Inlines -> Inlines) -> Inlines -> Inlines
protectCase (forall a. CiteprocOutput a => Maybe Lang -> TextCase -> a -> a
addTextCase Maybe Lang
mblang TextCase
SentenceCase)

getTitle :: Text -> Bib Inlines
getTitle :: Text -> Bib Inlines
getTitle Text
f = do
  Inlines
ils <- Text -> Bib Inlines
getField Text
f
  Bool
utc <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets BibState -> Bool
untitlecase
  Lang
lang <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets BibState -> Lang
localeLang
  let ils' :: Inlines
ils' =
        if Text
f forall a. Eq a => a -> a -> Bool
== Text
"series"
           then Lang -> Inlines -> Inlines
resolveKey Lang
lang Inlines
ils
           else Inlines
ils
  let processTitle :: Inlines -> Inlines
processTitle = if Bool
utc then Maybe Lang -> Inlines -> Inlines
unTitlecase (forall a. a -> Maybe a
Just Lang
lang) else forall a. a -> a
id
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Inlines -> Inlines
processTitle Inlines
ils'

getShortTitle :: Bool -> Text -> Bib (Maybe Inlines)
getShortTitle :: Bool -> Text -> RWST Item () BibState BibParser (Maybe Inlines)
getShortTitle Bool
requireColon Text
f = do
  [Inline]
ils <- (Char -> Bool) -> [Inline] -> [Inline]
splitStrWhen (forall a. Eq a => a -> a -> Bool
==Char
':') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Many a -> [a]
B.toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getTitle Text
f
  if Bool -> Bool
not Bool
requireColon Bool -> Bool -> Bool
|| [Inline] -> Bool
containsColon [Inline]
ils
     then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Many a
B.fromList forall a b. (a -> b) -> a -> b
$ [Inline] -> [Inline]
upToColon [Inline]
ils
     else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing

containsColon :: [Inline] -> Bool
containsColon :: [Inline] -> Bool
containsColon [Inline]
xs = Text -> Inline
Str Text
":" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Inline]
xs

upToColon :: [Inline] -> [Inline]
upToColon :: [Inline] -> [Inline]
upToColon [Inline]
xs = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a. Eq a => a -> a -> Bool
/= Text -> Inline
Str Text
":") [Inline]
xs

isNumber :: Text -> Bool
isNumber :: Text -> Bool
isNumber Text
t = case Text -> Maybe (Char, Text)
T.uncons Text
t of
  Just (Char
'-', Text
ds) -> (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isDigit Text
ds
  Just (Char, Text)
_         -> (Char -> Bool) -> Text -> Bool
T.all Char -> Bool
isDigit Text
t
  Maybe (Char, Text)
Nothing        -> Bool
False

getDate :: Text -> Bib Date
getDate :: Text -> RWST Item () BibState BibParser Date
getDate Text
f = do
  -- the ~ can used for approx dates, but the latex reader
  -- parses this as a nonbreaking space, so we need to convert it back!
  let nbspToTilde :: Char -> Char
nbspToTilde Char
'\160' = Char
'~'
      nbspToTilde Char
c      = Char
c
  Maybe Date
mbd <- Text -> Maybe Date
rawDateEDTF forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> Text -> Text
T.map Char -> Char
nbspToTilde forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
f
  case Maybe Date
mbd of
    Maybe Date
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"expected date"
    Just Date
d  -> forall (m :: * -> *) a. Monad m => a -> m a
return Date
d

-- A negative (BC) year might be written with -- or --- in bibtex:
fixLeadingDash :: Text -> Text
fixLeadingDash :: Text -> Text
fixLeadingDash Text
t = case Text -> Maybe (Char, Text)
T.uncons Text
t of
  Just (Char
c, Text
ds) | (Char
c forall a. Eq a => a -> a -> Bool
== Char
'–' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'—') Bool -> Bool -> Bool
&& Text -> Bool
firstIsDigit Text
ds -> Char -> Text -> Text
T.cons Char
'–' Text
ds
  Maybe (Char, Text)
_ -> Text
t
 where firstIsDigit :: Text -> Bool
firstIsDigit = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (Char -> Bool
isDigit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe (Char, Text)
T.uncons

getOldDate :: Text -> Bib Date
getOldDate :: Text -> RWST Item () BibState BibParser Date
getOldDate Text
prefix = do
  Maybe Int
year' <- (forall a. Read a => String -> Maybe a
readMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
fixLeadingDash forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify
              forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"year")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  Maybe Int
month' <- (Text -> Maybe Int
parseMonth forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"month"))
            forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  Maybe Int
day' <- (forall a. Read a => String -> Maybe a
readMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"day"))
          forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  Maybe Int
endyear' <- (forall a. Read a => String -> Maybe a
readMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
fixLeadingDash forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify
              forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"endyear")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  Maybe Int
endmonth' <- (Text -> Maybe Int
parseMonth forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify
                 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Inlines
getField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"endmonth")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  Maybe Int
endday' <- (forall a. Read a => String -> Maybe a
readMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Walkable Inline a => a -> Text
stringify forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                 Text -> Bib Inlines
getField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"endday")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  let toDateParts :: (Maybe Int, Maybe Int, Maybe Int) -> DateParts
toDateParts (Maybe Int
y', Maybe Int
m', Maybe Int
d') =
              [Int] -> DateParts
DateParts forall a b. (a -> b) -> a -> b
$
                 case Maybe Int
y' of
                   Maybe Int
Nothing -> []
                   Just Int
y  ->
                     case Maybe Int
m' of
                       Maybe Int
Nothing -> [Int
y]
                       Just Int
m  ->
                         case Maybe Int
d' of
                           Maybe Int
Nothing -> [Int
y,Int
m]
                           Just Int
d  -> [Int
y,Int
m,Int
d]
  let dateparts :: [DateParts]
dateparts = forall a. (a -> Bool) -> [a] -> [a]
filter (\DateParts
x -> DateParts
x forall a. Eq a => a -> a -> Bool
/= [Int] -> DateParts
DateParts [])
                  forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (Maybe Int, Maybe Int, Maybe Int) -> DateParts
toDateParts [(Maybe Int
year',Maybe Int
month',Maybe Int
day'),
                                     (Maybe Int
endyear',Maybe Int
endmonth',Maybe Int
endday')]
  Maybe Text
literal' <- if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DateParts]
dateparts
                 then forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField (Text
prefix forall a. Semigroup a => a -> a -> a
<> Text
"year")
                 else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    Date { dateParts :: [DateParts]
dateParts = [DateParts]
dateparts
         , dateCirca :: Bool
dateCirca = Bool
False
         , dateSeason :: Maybe Int
dateSeason = forall a. Maybe a
Nothing
         , dateLiteral :: Maybe Text
dateLiteral = Maybe Text
literal' }

getRawField :: Text -> Bib Text
getRawField :: Text -> Bib Text
getRawField Text
f = do
  StringMap
fs <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> StringMap
fields
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
f StringMap
fs of
       Just Text
x  -> forall (m :: * -> *) a. Monad m => a -> m a
return Text
x
       Maybe Text
Nothing -> forall a. Text -> Bib a
notFound Text
f

getLiteralList :: Text -> Bib [Inlines]
getLiteralList :: Text -> Bib [Inlines]
getLiteralList Text
f = do
  StringMap
fs <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> StringMap
fields
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
f StringMap
fs of
       Just Text
x  -> Text -> Bib [Block]
latex' Text
x forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Block] -> Bib [Inlines]
toLiteralList
       Maybe Text
Nothing -> forall a. Text -> Bib a
notFound Text
f

-- separates items with semicolons
getLiteralList' :: Text -> Bib Inlines
getLiteralList' :: Text -> Bib Inlines
getLiteralList' Text
f = do
  StringMap
fs <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> StringMap
fields
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
f StringMap
fs of
    Just Text
x    -> do
      [Block]
x' <- Text -> Bib [Block]
latex' Text
x
      case [Block]
x' of
        [Para [Inline]
xs]  ->
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Many a
B.fromList
                 forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
intercalate [Text -> Inline
Str Text
";", Inline
Space]
                 forall a b. (a -> b) -> a -> b
$ [Inline] -> [[Inline]]
splitByAnd [Inline]
xs
        [Plain [Inline]
xs] ->
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Many a
B.fromList
                 forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
intercalate [Text -> Inline
Str Text
";", Inline
Space]
                 forall a b. (a -> b) -> a -> b
$ [Inline] -> [[Inline]]
splitByAnd [Inline]
xs
        [Block]
_          -> forall (m :: * -> *) a. MonadPlus m => m a
mzero
    Maybe Text
Nothing   -> forall a. Text -> Bib a
notFound Text
f

splitByAnd :: [Inline] -> [[Inline]]
splitByAnd :: [Inline] -> [[Inline]]
splitByAnd = forall a. Eq a => [a] -> [a] -> [[a]]
splitOn [Inline
Space, Text -> Inline
Str Text
"and", Inline
Space]

toLiteralList :: [Block] -> Bib [Inlines]
toLiteralList :: [Block] -> Bib [Inlines]
toLiteralList [Para [Inline]
xs] =
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a. [a] -> Many a
B.fromList forall a b. (a -> b) -> a -> b
$ [Inline] -> [[Inline]]
splitByAnd [Inline]
xs
toLiteralList [Plain [Inline]
xs] = [Block] -> Bib [Inlines]
toLiteralList [[Inline] -> Block
Para [Inline]
xs]
toLiteralList [Block]
_ = forall (m :: * -> *) a. MonadPlus m => m a
mzero

concatWith :: Char -> [Inlines] -> Inlines
concatWith :: Char -> [Inlines] -> Inlines
concatWith Char
sep = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Inlines -> Inlines -> Inlines
go forall a. Monoid a => a
mempty
  where go :: Inlines -> Inlines -> Inlines
        go :: Inlines -> Inlines -> Inlines
go Inlines
accum Inlines
s
          | Inlines
s forall a. Eq a => a -> a -> Bool
== forall a. Monoid a => a
mempty = Inlines
accum
          | Bool
otherwise   =
              case forall a. Seq a -> ViewR a
Seq.viewr (forall a. Many a -> Seq a
B.unMany Inlines
accum) of
                     ViewR Inline
Seq.EmptyR -> Inlines
s
                     Seq Inline
_ Seq.:> Str Text
x
                       | Bool -> Bool
not (Text -> Bool
T.null Text
x) Bool -> Bool -> Bool
&&
                         Text -> Char
T.last Text
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (String
"!?.,:;" :: String)
                                    -> Inlines
accum forall a. Semigroup a => a -> a -> a
<> Inlines
B.space forall a. Semigroup a => a -> a -> a
<> Inlines
s
                     ViewR Inline
_ -> Inlines
accum forall a. Semigroup a => a -> a -> a
<> Text -> Inlines
B.str (Char -> Text
T.singleton Char
sep) forall a. Semigroup a => a -> a -> a
<>
                                                Inlines
B.space forall a. Semigroup a => a -> a -> a
<> Inlines
s


parseOptions :: Text -> [(Text, Text)]
parseOptions :: Text -> [(Text, Text)]
parseOptions = forall a b. (a -> b) -> [a] -> [b]
map Text -> (Text, Text)
breakOpt forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> [Text]
T.splitOn Text
","
  where breakOpt :: Text -> (Text, Text)
breakOpt Text
x = case (Char -> Bool) -> Text -> (Text, Text)
T.break (forall a. Eq a => a -> a -> Bool
==Char
'=') Text
x of
                          (Text
w,Text
v) -> (Text -> Text
T.toLower forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip Text
w,
                                    Text -> Text
T.toLower forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip forall a b. (a -> b) -> a -> b
$ Int -> Text -> Text
T.drop Int
1 Text
v)

optionSet :: Text -> [(Text, Text)] -> Bool
optionSet :: Text -> [(Text, Text)] -> Bool
optionSet Text
key [(Text, Text)]
opts = case forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
key [(Text, Text)]
opts of
                      Just Text
"true" -> Bool
True
                      Just Text
s      -> Text
s forall a. Eq a => a -> a -> Bool
== forall a. Monoid a => a
mempty
                      Maybe Text
_           -> Bool
False

getNameList :: [(Text, Text)] -> Text -> Bib [Name]
getNameList :: [(Text, Text)] -> Text -> Bib [Name]
getNameList [(Text, Text)]
opts  Text
f = do
  StringMap
fs <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> StringMap
fields
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
f StringMap
fs of
       Just Text
x  -> NameOpts -> Text -> Bib [Name]
latexNames NameOpts
nameopts Text
x
       Maybe Text
Nothing -> forall a. Text -> Bib a
notFound Text
f
 where
  nameopts :: NameOpts
nameopts = NameOpts{
                 nameOptsPrefixIsNonDroppingParticle :: Bool
nameOptsPrefixIsNonDroppingParticle = Text -> [(Text, Text)] -> Bool
optionSet Text
"useprefix" [(Text, Text)]
opts,
                 nameOptsUseJuniorComma :: Bool
nameOptsUseJuniorComma = Text -> [(Text, Text)] -> Bool
optionSet Text
"juniorcomma" [(Text, Text)]
opts}

toNameList :: NameOpts -> [Block] -> Bib [Name]
toNameList :: NameOpts -> [Block] -> Bib [Name]
toNameList NameOpts
opts [Para [Inline]
xs] =
  forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. Eq a => a -> a -> Bool
/= Name
emptyName) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *). Monad m => NameOpts -> [Inline] -> m Name
toName NameOpts
opts forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> [Inline]
addSpaceAfterPeriod)
                                    ([Inline] -> [[Inline]]
splitByAnd [Inline]
xs)
toNameList NameOpts
opts [Plain [Inline]
xs] = NameOpts -> [Block] -> Bib [Name]
toNameList NameOpts
opts [[Inline] -> Block
Para [Inline]
xs]
toNameList NameOpts
_ [Block]
_ = forall (m :: * -> *) a. MonadPlus m => m a
mzero

latexNames :: NameOpts -> Text -> Bib [Name]
latexNames :: NameOpts -> Text -> Bib [Name]
latexNames NameOpts
opts Text
t = Text -> Bib [Block]
latex' (Text -> Text
T.strip Text
t) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= NameOpts -> [Block] -> Bib [Name]
toNameList NameOpts
opts

-- see issue 392 for motivation.  We want to treat
-- "J.G. Smith" and "J. G. Smith" the same.
addSpaceAfterPeriod :: [Inline] -> [Inline]
addSpaceAfterPeriod :: [Inline] -> [Inline]
addSpaceAfterPeriod = [Inline] -> [Inline]
go forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> [Inline] -> [Inline]
splitStrWhen (forall a. Eq a => a -> a -> Bool
==Char
'.')
  where
    go :: [Inline] -> [Inline]
go [] = []
    go (Str (Text -> String
T.unpack -> [Char
c]):Str Text
".":Str (Text -> String
T.unpack -> [Char
d]):[Inline]
xs)
      | Char -> Bool
isLetter Char
d
      , Char -> Bool
isLetter Char
c
      , Char -> Bool
isUpper Char
c
      , Char -> Bool
isUpper Char
d
        = Text -> Inline
Str (Char -> Text
T.singleton Char
c)forall a. a -> [a] -> [a]
:Text -> Inline
Str Text
"."forall a. a -> [a] -> [a]
:Inline
Spaceforall a. a -> [a] -> [a]
:[Inline] -> [Inline]
go (Text -> Inline
Str (Char -> Text
T.singleton Char
d)forall a. a -> [a] -> [a]
:[Inline]
xs)
    go (Inline
x:[Inline]
xs) = Inline
xforall a. a -> [a] -> [a]
:[Inline] -> [Inline]
go [Inline]
xs

ordinalize :: Locale -> Text -> Text
ordinalize :: Locale -> Text -> Text
ordinalize Locale
locale Text
n =
  let terms :: Map Text [(Term, Text)]
terms = Locale -> Map Text [(Term, Text)]
localeTerms Locale
locale
      pad0 :: Text -> Text
pad0 Text
t = case Text -> Int
T.length Text
t of
                 Int
0 -> Text
"00"
                 Int
1 -> Text
"0" forall a. Semigroup a => a -> a -> a
<> Text
t
                 Int
_ -> Text
t
   in case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Text
"ordinal-" forall a. Semigroup a => a -> a -> a
<> Text -> Text
pad0 Text
n) Map Text [(Term, Text)]
terms forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
           forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
"ordinal" Map Text [(Term, Text)]
terms of
        Maybe [(Term, Text)]
Nothing    -> Text
n
        Just []    -> Text
n
        Just ((Term, Text)
t:[(Term, Text)]
_) -> Text
n forall a. Semigroup a => a -> a -> a
<> forall a b. (a, b) -> b
snd (Term, Text)
t

getTypeAndGenre :: Bib (Text, Maybe Text)
getTypeAndGenre :: Bib (Text, Maybe Text)
getTypeAndGenre = do
  Lang
lang <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets BibState -> Lang
localeLang
  Text
et <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks Item -> Text
entryType
  Text
reftype' <- Lang -> Text -> Text
resolveKey' Lang
lang forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Bib Text
getRawField Text
"type"
         forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
  Text
st <- Text -> Bib Text
getRawField Text
"entrysubtype" forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
  Bool
isEvent <- (Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (Text -> Bib Text
getRawField Text
"eventdate"
                     forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Text
getRawField Text
"eventtitle"
                     forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Bib Text
getRawField Text
"venue")) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
  let reftype :: Text
reftype =
        case Text
et of
           Text
"article"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"magazine"  -> Text
"article-magazine"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"newspaper" -> Text
"article-newspaper"
             | Bool
otherwise         -> Text
"article-journal"
           Text
"book"                -> Text
"book"
           Text
"booklet"             -> Text
"pamphlet"
           Text
"bookinbook"          -> Text
"chapter"
           Text
"collection"          -> Text
"book"
           Text
"dataset"             -> Text
"dataset"
           Text
"electronic"          -> Text
"webpage"
           Text
"inbook"              -> Text
"chapter"
           Text
"incollection"        -> Text
"chapter"
           Text
"inreference"         -> Text
"entry-encyclopedia"
           Text
"inproceedings"       -> Text
"paper-conference"
           Text
"manual"              -> Text
"book"
           Text
"mastersthesis"       -> Text
"thesis"
           Text
"misc"                -> Text
""
           Text
"mvbook"              -> Text
"book"
           Text
"mvcollection"        -> Text
"book"
           Text
"mvproceedings"       -> Text
"book"
           Text
"mvreference"         -> Text
"book"
           Text
"online"              -> Text
"webpage"
           Text
"patent"              -> Text
"patent"
           Text
"periodical"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"magazine"  -> Text
"article-magazine"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"newspaper" -> Text
"article-newspaper"
             | Bool
otherwise         -> Text
"article-journal"
           Text
"phdthesis"           -> Text
"thesis"
           Text
"proceedings"         -> Text
"book"
           Text
"reference"           -> Text
"book"
           Text
"report"              -> Text
"report"
           Text
"software"            -> Text
"software"
           Text
"suppbook"            -> Text
"chapter"
           Text
"suppcollection"      -> Text
"chapter"
           Text
"suppperiodical"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"magazine"  -> Text
"article-magazine"
             | Text
st forall a. Eq a => a -> a -> Bool
== Text
"newspaper" -> Text
"article-newspaper"
             | Bool
otherwise         -> Text
"article-journal"
           Text
"techreport"          -> Text
"report"
           Text
"thesis"              -> Text
"thesis"
           Text
"unpublished"         -> if Bool
isEvent then Text
"speech" else Text
"manuscript"
           Text
"www"                 -> Text
"webpage"
           -- biblatex, "unsupported"
           Text
"artwork"             -> Text
"graphic"
           Text
"audio"               -> Text
"song"    -- for audio *recordings*
           Text
"commentary"          -> Text
"book"
           Text
"image"               -> Text
"graphic"   -- or "figure" ?
           Text
"jurisdiction"        -> Text
"legal_case"
           Text
"legislation"         -> Text
"legislation"  -- or "bill" ?
           Text
"legal"               -> Text
"treaty"
           Text
"letter"              -> Text
"personal_communication"
           Text
"movie"               -> Text
"motion_picture"
           Text
"music"               -> Text
"song"        -- for musical *recordings*
           Text
"performance"         -> Text
"speech"
           Text
"review"              -> Text
"review"      -- or "review-book" ?
           Text
"standard"            -> Text
"legislation"
           Text
"video"               -> Text
"motion_picture"
           -- biblatex-apa:
           Text
"data"                -> Text
"dataset"
           Text
"letters"             -> Text
"personal_communication"
           Text
"newsarticle"         -> Text
"article-newspaper"
           Text
_                     -> Text
""

  let refgenre :: Maybe Text
refgenre =
        case Text
et of
          Text
"mastersthesis"  -> if Text -> Bool
T.null Text
reftype'
                                 then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Text
resolveKey' Lang
lang Text
"mathesis"
                                 else forall a. a -> Maybe a
Just Text
reftype'
          Text
"phdthesis"      -> if Text -> Bool
T.null Text
reftype'
                                 then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Text
resolveKey' Lang
lang Text
"phdthesis"
                                 else forall a. a -> Maybe a
Just Text
reftype'
          Text
_                -> if Text -> Bool
T.null Text
reftype'
                                 then forall a. Maybe a
Nothing
                                 else forall a. a -> Maybe a
Just Text
reftype'
  forall (m :: * -> *) a. Monad m => a -> m a
return (Text
reftype, Maybe Text
refgenre)


-- transformKey source target key
-- derived from Appendix C of bibtex manual
transformKey :: Text -> Text -> Text -> [Text]
transformKey :: Text -> Text -> Text -> [Text]
transformKey Text
_ Text
_ Text
"ids"            = []
transformKey Text
_ Text
_ Text
"crossref"       = []
transformKey Text
_ Text
_ Text
"xref"           = []
transformKey Text
_ Text
_ Text
"entryset"       = []
transformKey Text
_ Text
_ Text
"entrysubtype"   = []
transformKey Text
_ Text
_ Text
"execute"        = []
transformKey Text
_ Text
_ Text
"label"          = []
transformKey Text
_ Text
_ Text
"options"        = []
transformKey Text
_ Text
_ Text
"presort"        = []
transformKey Text
_ Text
_ Text
"related"        = []
transformKey Text
_ Text
_ Text
"relatedoptions" = []
transformKey Text
_ Text
_ Text
"relatedstring"  = []
transformKey Text
_ Text
_ Text
"relatedtype"    = []
transformKey Text
_ Text
_ Text
"shorthand"      = []
transformKey Text
_ Text
_ Text
"shorthandintro" = []
transformKey Text
_ Text
_ Text
"sortkey"        = []
transformKey Text
x Text
y Text
"author"
  | Text
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"mvbook", Text
"book"] Bool -> Bool -> Bool
&&
    Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"inbook", Text
"bookinbook", Text
"suppbook"] = [Text
"bookauthor", Text
"author"]
-- note: this next clause is not in the biblatex manual, but it makes
-- sense in the context of CSL conversion:
transformKey Text
x Text
y Text
"author"
  | Text
x forall a. Eq a => a -> a -> Bool
== Text
"mvbook" Bool -> Bool -> Bool
&& Text
y forall a. Eq a => a -> a -> Bool
== Text
"book" = [Text
"bookauthor", Text
"author"]
transformKey Text
"mvbook" Text
y Text
z
  | Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"book", Text
"inbook", Text
"bookinbook", Text
"suppbook"] = Text -> [Text]
standardTrans Text
z
transformKey Text
x Text
y Text
z
  | Text
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"mvcollection", Text
"mvreference"] Bool -> Bool -> Bool
&&
    Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"collection", Text
"reference", Text
"incollection", Text
"inreference",
               Text
"suppcollection"] = Text -> [Text]
standardTrans Text
z
transformKey Text
"mvproceedings" Text
y Text
z
  | Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"proceedings", Text
"inproceedings"] = Text -> [Text]
standardTrans Text
z
transformKey Text
"book" Text
y Text
z
  | Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"inbook", Text
"bookinbook", Text
"suppbook"] = Text -> [Text]
bookTrans Text
z
transformKey Text
x Text
y Text
z
  | Text
x forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"collection", Text
"reference"] Bool -> Bool -> Bool
&&
    Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"incollection", Text
"inreference", Text
"suppcollection"] = Text -> [Text]
bookTrans Text
z
transformKey Text
"proceedings" Text
"inproceedings" Text
z = Text -> [Text]
bookTrans Text
z
transformKey Text
"periodical" Text
y Text
z
  | Text
y forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"article", Text
"suppperiodical"] =
  case Text
z of
       Text
"title"          -> [Text
"journaltitle"]
       Text
"subtitle"       -> [Text
"journalsubtitle"]
       Text
"shorttitle"     -> []
       Text
"sorttitle"      -> []
       Text
"indextitle"     -> []
       Text
"indexsorttitle" -> []
       Text
_                -> [Text
z]
transformKey Text
_ Text
_ Text
x                = [Text
x]

standardTrans :: Text -> [Text]
standardTrans :: Text -> [Text]
standardTrans Text
z =
  case Text
z of
       Text
"title"          -> [Text
"maintitle"]
       Text
"subtitle"       -> [Text
"mainsubtitle"]
       Text
"titleaddon"     -> [Text
"maintitleaddon"]
       Text
"shorttitle"     -> []
       Text
"sorttitle"      -> []
       Text
"indextitle"     -> []
       Text
"indexsorttitle" -> []
       Text
_                -> [Text
z]

bookTrans :: Text -> [Text]
bookTrans :: Text -> [Text]
bookTrans Text
z =
  case Text
z of
       Text
"title"          -> [Text
"booktitle"]
       Text
"subtitle"       -> [Text
"booksubtitle"]
       Text
"titleaddon"     -> [Text
"booktitleaddon"]
       Text
"shorttitle"     -> []
       Text
"sorttitle"      -> []
       Text
"indextitle"     -> []
       Text
"indexsorttitle" -> []
       Text
_                -> [Text
z]

resolveKey :: Lang -> Inlines -> Inlines
resolveKey :: Lang -> Inlines -> Inlines
resolveKey Lang
lang (Many Seq Inline
ils) = forall a. Seq a -> Many a
Many forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Inline -> Inline
go Seq Inline
ils
  where go :: Inline -> Inline
go (Str Text
s) = Text -> Inline
Str forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Text
resolveKey' Lang
lang Text
s
        go Inline
x       = Inline
x

resolveKey' :: Lang -> Text -> Text
resolveKey' :: Lang -> Text -> Text
resolveKey' Lang
lang Text
k =
  case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Lang -> Text
langLanguage Lang
lang) Map Text (Map Text (Text, Text))
biblatexStringMap forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
        forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
k of
    Maybe (Text, Text)
Nothing     -> Text
k
    Just (Text
x, Text
_) -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> b -> a
const Text
k) forall a. Walkable Inline a => a -> Text
stringify forall a b. (a -> b) -> a -> b
$ Lang -> Text -> Either PandocError [Block]
parseLaTeX Lang
lang Text
x

convertEnDash :: Inline -> Inline
convertEnDash :: Inline -> Inline
convertEnDash (Str Text
s) = Text -> Inline
Str ((Char -> Char) -> Text -> Text
T.map (\Char
c -> if Char
c forall a. Eq a => a -> a -> Bool
== Char
'–' then Char
'-' else Char
c) Text
s)
convertEnDash Inline
x       = Inline
x