    {-# LANGUAGE OverloadedStrings #-}
    module Text.Pandoc.Citeproc.CslJson
      ( cslJsonToReferences )
    where

    import Citeproc.CslJson
    import Citeproc.Types
    import Control.Monad.Identity (runIdentity)
    import Data.Aeson (eitherDecodeStrict', FromJSON(parseJSON), (.:), Value(..))
    import Data.Aeson.Types (parseEither)
    import Data.ByteString (ByteString)
    import Text.Pandoc.Builder as B
    import Data.Text (Text)

    fromCslJson :: CslJson Text -> Inlines
    fromCslJson :: CslJson Text -> Inlines
    fromCslJson (CslText Text
    t) = Text -> Inlines
    B.text Text
    t
    fromCslJson CslJson Text
    CslEmpty = Inlines
    forall a. Monoid a => a
    mempty
    fromCslJson (CslConcat CslJson Text
    x CslJson Text
    y) = CslJson Text -> Inlines
    fromCslJson CslJson Text
    x Inlines -> Inlines -> Inlines
    forall a. Semigroup a => a -> a -> a
    <> CslJson Text -> Inlines
    fromCslJson CslJson Text
    y
    fromCslJson (CslQuoted CslJson Text
    x) = Inlines -> Inlines
    B.doubleQuoted (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslItalic CslJson Text
    x) = Inlines -> Inlines
    B.emph (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslNormal CslJson Text
    x) = CslJson Text -> Inlines
    fromCslJson CslJson Text
    x  -- TODO?
    fromCslJson (CslBold CslJson Text
    x) = Inlines -> Inlines
    B.strong (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslUnderline CslJson Text
    x) = Inlines -> Inlines
    B.underline (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslNoDecoration CslJson Text
    x) =
      Attr -> Inlines -> Inlines
    B.spanWith (Text
    "",[Text
    "nodecoration"],[]) (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslSmallCaps CslJson Text
    x) = Inlines -> Inlines
    B.smallcaps (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslBaseline CslJson Text
    x) = CslJson Text -> Inlines
    fromCslJson CslJson Text
    x
    fromCslJson (CslSub CslJson Text
    x) = Inlines -> Inlines
    B.subscript (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslSup CslJson Text
    x) = Inlines -> Inlines
    B.superscript (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslNoCase CslJson Text
    x) = Attr -> Inlines -> Inlines
    B.spanWith (Text
    "",[Text
    "nocase"],[]) (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslDiv Text
    t CslJson Text
    x) = Attr -> Inlines -> Inlines
    B.spanWith (Text
    "",[Text
    "csl-" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    t],[]) (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)
    fromCslJson (CslLink Text
    u CslJson Text
    x) = Text -> Text -> Inlines -> Inlines
    B.link Text
    u Text
    "" (CslJson Text -> Inlines
    fromCslJson CslJson Text
    x)

    cslJsonToReferences :: ByteString -> Either String [Reference Inlines]
    cslJsonToReferences :: ByteString -> Either String [Reference Inlines]
    cslJsonToReferences ByteString
    raw = do
      items <-
        case ByteString -> Either String Value
    forall a. FromJSON a => ByteString -> Either String a
    eitherDecodeStrict' ByteString
    raw of
          Left String
    e -> String -> Either String [Reference (CslJson Text)]
    forall a b. a -> Either a b
    Left String
    e
          Right (Object Object
    o) -> (Object -> Parser [Reference (CslJson Text)])
    -> Object -> Either String [Reference (CslJson Text)]
    forall a b. (a -> Parser b) -> a -> Either String b
    parseEither (Object -> Key -> Parser [Reference (CslJson Text)]
    forall a. FromJSON a => Object -> Key -> Parser a
    .: Key
    "items") Object
    o
          Right val :: Value
    val@(Array Array
    _) -> (Value -> Parser [Reference (CslJson Text)])
    -> Value -> Either String [Reference (CslJson Text)]
    forall a b. (a -> Parser b) -> a -> Either String b
    parseEither Value -> Parser [Reference (CslJson Text)]
    forall a. FromJSON a => Value -> Parser a
    parseJSON Value
    val
          Right Value
    _ -> String -> Either String [Reference (CslJson Text)]
    forall a b. a -> Either a b
    Left String
    "expecting Object or Array"
      pure $ map (runIdentity . traverse (return . fromCslJson)) items