{-# LANGUAGE TupleSections #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Readers.EndNote
   Copyright   : Copyright (C) 2022-2024 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Parses EndNote XML bibliographies into a Pandoc document
with empty body and `references` and `nocite` fields
in the metadata.  A wildcard `nocite` is used so that
if the document is rendered in another format, the
entire bibliography will be printed.
-}
module Text.Pandoc.Readers.EndNote
  ( readEndNoteXML
  , readEndNoteXMLCitation
  )
where

import Text.Pandoc.Options
import Text.Pandoc.Definition
import Citeproc (Reference(..), ItemId(..), Val(..), Date(..), DateParts(..))
import qualified Citeproc
import Text.Pandoc.Builder as B
import Text.Pandoc.Error (PandocError(..))
import Text.Pandoc.Class (PandocMonad)
import Text.Pandoc.Citeproc.MetaValue (referenceToMetaValue)
import Text.Pandoc.Sources (Sources(..), ToSources(..), sourcesToText)
import Text.Pandoc.Citeproc.Name (toName, NameOpts(..))
import Control.Applicative ((<|>))
import Control.Monad.Except (throwError)
import Control.Monad (mzero, unless)
import Text.Pandoc.XML.Light
    ( filterElementName,
      strContent,
      QName(qName),
      Element(..),
      Content(..),
      CData(..),
      filterElementsName,
      filterChildName,
      filterChildrenName,
      findAttrBy,
      parseXMLElement )
import qualified Data.Text.Lazy as TL
import qualified Data.Text as T
import Data.Text (Text)
import qualified Data.Map as M
import Safe (readMay)

-- | Read EndNote XML from an input string and return a Pandoc document.
-- The document will have only metadata, with an empty body.
-- The metadata will contain a `references` field with the
-- bibliography entries, and a `nocite` field with the wildcard `[@*]`.
readEndNoteXML :: (PandocMonad m, ToSources a)
               => ReaderOptions -> a -> m Pandoc
readEndNoteXML :: forall (m :: * -> *) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> a -> m Pandoc
readEndNoteXML ReaderOptions
_opts a
inp = do
  let sources :: Sources
sources = a -> Sources
forall a. ToSources a => a -> Sources
toSources a
inp
  refs <- Sources -> m [Reference Text]
forall (m :: * -> *).
PandocMonad m =>
Sources -> m [Reference Text]
readEndNoteXMLReferences Sources
sources m [Reference Text]
-> ([Reference Text] -> m [Reference Inlines])
-> m [Reference Inlines]
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Reference Text -> m (Reference Inlines))
-> [Reference Text] -> m [Reference Inlines]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((Text -> m Inlines) -> Reference Text -> m (Reference Inlines)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Reference a -> f (Reference b)
traverse (Inlines -> m Inlines
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Inlines -> m Inlines) -> (Text -> Inlines) -> Text -> m Inlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Inlines
text))
  return $
    setMeta "nocite" (cite [Citation {citationId = "*"
                                     , citationPrefix = []
                                     , citationSuffix = []
                                     , citationMode = NormalCitation
                                     , citationNoteNum = 0
                                     , citationHash = 0}] (str "[@*]")) $
    setMeta "references" (map referenceToMetaValue refs) $
    B.doc mempty

readEndNoteXMLCitation :: PandocMonad m
                    => Text -> m (Citeproc.Citation Text)
readEndNoteXMLCitation :: forall (m :: * -> *). PandocMonad m => Text -> m (Citation Text)
readEndNoteXMLCitation Text
xml = do
  tree <- (Text -> m Element)
-> (Element -> m Element) -> Either Text Element -> m Element
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (PandocError -> m Element
forall a. PandocError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Element)
-> (Text -> PandocError) -> Text -> m Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> PandocError
PandocXMLError Text
"EndNote references") Element -> m Element
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text Element -> m Element)
-> Either Text Element -> m Element
forall a b. (a -> b) -> a -> b
$
              Text -> Either Text Element
parseXMLElement (Text -> Text
TL.fromStrict Text
xml)
  unless (qName (elName tree) == "EndNote") $
    throwError $ PandocXMLError "EndNote references" "Expected EndNote element"
  let items = (Element -> CitationItem Text) -> [Element] -> [CitationItem Text]
forall a b. (a -> b) -> [a] -> [b]
map Element -> CitationItem Text
toCitationItem ([Element] -> [CitationItem Text])
-> [Element] -> [CitationItem Text]
forall a b. (a -> b) -> a -> b
$ (QName -> Bool) -> Element -> [Element]
filterElementsName (Text -> QName -> Bool
name Text
"Cite") Element
tree
  return $ Citeproc.Citation{
                     Citeproc.citationId = Nothing
                   , Citeproc.citationNoteNumber = Nothing
                   , Citeproc.citationItems = items
                   }

readEndNoteXMLReferences :: PandocMonad m
                         => Sources -> m [Reference Text]
readEndNoteXMLReferences :: forall (m :: * -> *).
PandocMonad m =>
Sources -> m [Reference Text]
readEndNoteXMLReferences Sources
sources = do
  tree <- (Text -> m Element)
-> (Element -> m Element) -> Either Text Element -> m Element
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (PandocError -> m Element
forall a. PandocError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Element)
-> (Text -> PandocError) -> Text -> m Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> PandocError
PandocXMLError Text
"EndNote references") Element -> m Element
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text Element -> m Element)
-> Either Text Element -> m Element
forall a b. (a -> b) -> a -> b
$
              Text -> Either Text Element
parseXMLElement (Text -> Text
TL.fromStrict (Text -> Text) -> (Sources -> Text) -> Sources -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sources -> Text
sourcesToText (Sources -> Text) -> Sources -> Text
forall a b. (a -> b) -> a -> b
$ Sources
sources)
  let records = (QName -> Bool) -> Element -> [Element]
filterElementsName (Text -> QName -> Bool
name Text
"record") Element
tree
  return $ map recordToReference records


toCitationItem :: Element -> Citeproc.CitationItem Text
toCitationItem :: Element -> CitationItem Text
toCitationItem Element
el =
    Citeproc.CitationItem{ citationItemId :: ItemId
Citeproc.citationItemId =
                              ItemId
-> (Reference Text -> ItemId) -> Maybe (Reference Text) -> ItemId
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ItemId
forall a. Monoid a => a
mempty Reference Text -> ItemId
forall a. Reference a -> ItemId
referenceId Maybe (Reference Text)
mbref
                         , citationItemLabel :: Maybe Text
Citeproc.citationItemLabel = Maybe Text
forall a. Maybe a
Nothing
                         , citationItemLocator :: Maybe Text
Citeproc.citationItemLocator = Maybe Text
mbpages
                         , citationItemType :: CitationItemType
Citeproc.citationItemType = CitationItemType
Citeproc.NormalCite
                         , citationItemPrefix :: Maybe Text
Citeproc.citationItemPrefix = Maybe Text
mbprefix
                         , citationItemSuffix :: Maybe Text
Citeproc.citationItemSuffix = Maybe Text
mbsuffix
                         , citationItemData :: Maybe (Reference Text)
Citeproc.citationItemData = Maybe (Reference Text)
mbref
                         }
 where
  mbref :: Maybe (Reference Text)
mbref = Element -> Reference Text
recordToReference (Element -> Reference Text)
-> Maybe Element -> Maybe (Reference Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QName -> Bool) -> Element -> Maybe Element
filterChildName (Text -> QName -> Bool
name Text
"record") Element
el
  mbprefix :: Maybe Text
mbprefix = Element -> Text
getText (Element -> Text) -> Maybe Element -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QName -> Bool) -> Element -> Maybe Element
filterChildName (Text -> QName -> Bool
name Text
"Prefix") Element
el
  mbsuffix :: Maybe Text
mbsuffix = Element -> Text
getText (Element -> Text) -> Maybe Element -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QName -> Bool) -> Element -> Maybe Element
filterChildName (Text -> QName -> Bool
name Text
"Suffix") Element
el
  mbpages :: Maybe Text
mbpages  = Element -> Text
getText (Element -> Text) -> Maybe Element -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QName -> Bool) -> Element -> Maybe Element
filterChildName (Text -> QName -> Bool
name Text
"Pages") Element
el

name :: Text -> (QName -> Bool)
name :: Text -> QName -> Bool
name Text
t = (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
t) (Text -> Bool) -> (QName -> Text) -> QName -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QName -> Text
qName

getText :: Element -> Text
getText :: Element -> Text
getText Element
el = Content -> Text
getText' (Element -> Content
Elem Element
el)
 where
  getText' :: Content -> Text
getText' (Elem Element
el') = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Content -> Text) -> [Content] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Content -> Text
getText' ([Content] -> [Text]) -> [Content] -> [Text]
forall a b. (a -> b) -> a -> b
$ Element -> [Content]
elContent Element
el'
  getText' (Text CData
cd) = CData -> Text
cdData CData
cd
  getText' (CRef Text
_) = Text
forall a. Monoid a => a
mempty

recordToReference :: Element -> Reference Text
recordToReference :: Element -> Reference Text
recordToReference Element
e =
  Reference{ referenceId :: ItemId
referenceId = Text -> ItemId
ItemId Text
refid,
             referenceType :: Text
referenceType = Text
reftype,
             referenceDisambiguation :: Maybe DisambiguationData
referenceDisambiguation = Maybe DisambiguationData
forall a. Maybe a
Nothing,
             referenceVariables :: Map Variable (Val Text)
referenceVariables = Map Variable (Val Text)
refvars }

 where
   -- get strContent, recursing inside style elements:
   refid :: Text
refid = Text -> (Element -> Text) -> Maybe Element -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
forall a. Monoid a => a
mempty (Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
strContent)
           ((QName -> Bool) -> Element -> Maybe Element
filterElementName (Text -> QName -> Bool
name Text
"key") Element
e
            Maybe Element -> Maybe Element -> Maybe Element
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (QName -> Bool) -> Element -> Maybe Element
filterElementName (Text -> QName -> Bool
name Text
"rec-number") Element
e)
   reftype :: Text
reftype = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"document" Text -> Text
toCslReferenceType
              ((QName -> Bool) -> Element -> Maybe Element
filterElementName (Text -> QName -> Bool
name Text
"ref-type") Element
e Maybe Element -> (Element -> Maybe Text) -> Maybe Text
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                (QName -> Bool) -> Element -> Maybe Text
findAttrBy (Text -> QName -> Bool
name Text
"name"))
   authors :: [Name]
authors =
     (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"contributors") Element
e [Element] -> (Element -> [Element]) -> [Element]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
     (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"authors") [Element] -> (Element -> [Element]) -> [Element]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
     (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"author") [Element] -> (Element -> [Name]) -> [Name]
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
          NameOpts -> [Inline] -> [Name]
forall (m :: * -> *). Monad m => NameOpts -> [Inline] -> m Name
toName NameOpts{ nameOptsPrefixIsNonDroppingParticle :: Bool
nameOptsPrefixIsNonDroppingParticle = Bool
False
                         , nameOptsUseJuniorComma :: Bool
nameOptsUseJuniorComma = Bool
False }
             ([Inline] -> [Name]) -> (Element -> [Inline]) -> Element -> [Name]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Inlines -> [Inline]
forall a. Many a -> [a]
B.toList (Inlines -> [Inline])
-> (Element -> Inlines) -> Element -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  Text -> Inlines
B.text (Text -> Inlines) -> (Element -> Text) -> Element -> Inlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText
   titles :: [(Variable, Val Text)]
titles = do
     x <- (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"titles") Element
e
     (key, name') <- [("title", "title"),
                      ("container-title", "secondary-title")]
     (key,) . FancyVal . T.strip . getText <$>
                    filterChildrenName (name name') x
   pages :: [(Variable, Val Text)]
pages = (Variable
"pages",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"pages") Element
e
   volume :: [(Variable, Val Text)]
volume = (Variable
"volume",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"volume") Element
e
   number :: [(Variable, Val Text)]
number = (Variable
"number",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"number") Element
e
   isbn :: [(Variable, Val Text)]
isbn = (Variable
"isbn",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"isbn") Element
e
   publisher :: [(Variable, Val Text)]
publisher = (Variable
"publisher",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"publisher") Element
e
   originalPublisher :: [(Variable, Val Text)]
originalPublisher =
     (Variable
"original-publisher",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"orig-pub") Element
e
   publisherPlace :: [(Variable, Val Text)]
publisherPlace =
     (Variable
"publisher-place",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"pub-location") Element
e
   abstract :: [(Variable, Val Text)]
abstract = (Variable
"abstract",) (Val Text -> (Variable, Val Text))
-> (Element -> Val Text) -> Element -> (Variable, Val Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Val Text
forall a. a -> Val a
FancyVal (Text -> Val Text) -> (Element -> Text) -> Element -> Val Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> Text) -> (Element -> Text) -> Element -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Text
getText (Element -> (Variable, Val Text))
-> [Element] -> [(Variable, Val Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"abstract") Element
e
   dates :: [(Variable, Val a)]
dates = (Variable
"issued",) (Val a -> (Variable, Val a))
-> (Element -> Val a) -> Element -> (Variable, Val a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Val a
forall {a}. Element -> Val a
toDate (Element -> (Variable, Val a)) -> [Element] -> [(Variable, Val a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"dates") Element
e
   toDate :: Element -> Val a
toDate Element
e' = Date -> Val a
forall a. Date -> Val a
DateVal (Date -> Val a) -> Date -> Val a
forall a b. (a -> b) -> a -> b
$
    Date { dateParts :: [DateParts]
dateParts = Element -> [DateParts]
toDateParts Element
e'
         , dateCirca :: Bool
dateCirca = Bool
False
         , dateSeason :: Maybe Int
dateSeason = Maybe Int
forall a. Maybe a
Nothing
         , dateLiteral :: Maybe Text
dateLiteral = Maybe Text
forall a. Maybe a
Nothing }
   toDateParts :: Element -> [DateParts]
toDateParts Element
e' = do
    x <- (QName -> Bool) -> Element -> [Element]
filterChildrenName (Text -> QName -> Bool
name Text
"year") Element
e'
    case readMay . T.unpack . T.strip . getText $ x of
      Maybe Int
Nothing -> [DateParts]
forall a. [a]
forall (m :: * -> *) a. MonadPlus m => m a
mzero
      Just Int
y  -> DateParts -> [DateParts]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (DateParts -> [DateParts]) -> DateParts -> [DateParts]
forall a b. (a -> b) -> a -> b
$ [Int] -> DateParts
DateParts [Int
y]

   refvars :: Map Variable (Val Text)
refvars = [(Variable, Val Text)] -> Map Variable (Val Text)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Variable, Val Text)] -> Map Variable (Val Text))
-> [(Variable, Val Text)] -> Map Variable (Val Text)
forall a b. (a -> b) -> a -> b
$
     [ (Variable
"author", [Name] -> Val Text
forall a. [Name] -> Val a
NamesVal [Name]
authors) | Bool -> Bool
not ([Name] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Name]
authors) ] [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
titles [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
pages [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
volume [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
number [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
isbn [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
forall {a}. [(Variable, Val a)]
dates [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
publisher [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
originalPublisher [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
publisherPlace [(Variable, Val Text)]
-> [(Variable, Val Text)] -> [(Variable, Val Text)]
forall a. [a] -> [a] -> [a]
++
     [(Variable, Val Text)]
abstract

toCslReferenceType :: Text -> Text
toCslReferenceType :: Text -> Text
toCslReferenceType Text
t =
  case Text
t of
    Text
"Aggregated Database" -> Text
"dataset"
    Text
"Ancient Text" -> Text
"classic"
    Text
"Artwork" -> Text
"graphic"
    Text
"Audiovisual Material" -> Text
"graphic"
    Text
"Bill" -> Text
"legislation"
    Text
"Blog" -> Text
"post-weblog"
    Text
"Book" -> Text
"book"
    Text
"Book Section" -> Text
"chapter"
    Text
"Case" -> Text
"legal_case"
    Text
"Catalog" -> Text
"document"
    Text
"Chart or Table" -> Text
"graphic"
    Text
"Classical Work" -> Text
"classic"
    Text
"Computer program" -> Text
"software"
    Text
"Conference Paper" -> Text
"article"
    Text
"Conference Proceedings" -> Text
"periodical"
    Text
"Dataset" -> Text
"dataset"
    Text
"Dictionary" -> Text
"book"
    Text
"Edited Book" -> Text
"book"
    Text
"Electronic Article" -> Text
"article"
    Text
"Electronic Book" -> Text
"book"
    Text
"Electronic Book Section" -> Text
"chapter"
    Text
"Encyclopedia" -> Text
"book"
    Text
"Equation" -> Text
"document"
    Text
"Figure" -> Text
"graphic"
    Text
"Film or Broadcast" -> Text
"motion_picture"
    Text
"Government Document" -> Text
"document"
    Text
"Grant" -> Text
"document"
    Text
"Hearing" -> Text
"hearing"
    Text
"Interview" -> Text
"interview"
    Text
"Journal Article" -> Text
"article-journal"
    Text
"Legal Rule or Regulation" -> Text
"regulation"
    Text
"Magazine Article" -> Text
"article-magazine"
    Text
"Manuscript" -> Text
"manuscript"
    Text
"Map" -> Text
"map"
    Text
"Music" -> Text
"musical_score"
    Text
"Newspaper Article" -> Text
"article-newspaper"
    Text
"Online Database" -> Text
"dataset"
    Text
"Online Multimedia" -> Text
"webpage"
    Text
"Pamphlet" -> Text
"pamphlet"
    Text
"Patent" -> Text
"patent"
    Text
"Personal Communication" -> Text
"personal_communication"
    Text
"Podcast" -> Text
"document"
    Text
"Press Release" -> Text
"report"
    Text
"Report" -> Text
"report"
    Text
"Serial" -> Text
"periodical"
    Text
"Standard" -> Text
"standard"
    Text
"Statute" -> Text
"legislation"
    Text
"Thesis" -> Text
"thesis"
    Text
"Unpublished Work" -> Text
"unpublished"
    Text
"Web Page" -> Text
"webpage"
    Text
_ -> Text
"document"