-- | Defines citation rendering functions for Markdown (and Jupyter).
module Language.Drasil.Markdown.Citation (
  -- * Types
  BibFormatter(..),
  -- * Citation Renderer
  renderCite
) where

import Prelude hiding ((<>))
import qualified Prelude as P ((<>))
import Data.List (sortBy)
import Text.PrettyPrint (Doc, text, (<>), hsep)
import Utils.Drasil (foldlList)

import Drasil.Printers.Common
import Language.Drasil (People, Person, fullName, rendPersLFM, rendPersLFM',
  rendPersLFM'', numList)
import Language.Drasil.Document (CitationKind(..))
import Language.Drasil.Config (StyleGuide(APA, MLA, Chicago), bibStyleH)
import Language.Drasil.Printing.AST (Spec(S, Ref), LinkType(External))
import Language.Drasil.Printing.Citation (CiteField(Year, Number, Volume, Title, Author,
  Editor, Pages, Type, Month, Organization, Institution, Chapter, HowPublished, School, Note,
  Journal, BookTitle, Publisher, Series, Address, Edition), HP(URL, Verb),
  Citation(Cite))
import Language.Drasil.Printing.Helpers (comm, dot, sufxer, sufxPrint)

-- | Data type that carries functions that vary for bib printing
data BibFormatter = BibFormatter {
  -- | Emphasis (italics) rendering
  BibFormatter -> Doc -> Doc
emph :: Doc -> Doc,
  -- | Spec rendering
  BibFormatter -> Spec -> Doc
spec :: Spec -> Doc
}

-- | Internal emphasis wrapper for citations.
em :: Doc -> Doc
em :: Doc -> Doc
em Doc
d = String -> Doc
text String
"<em>" Doc -> Doc -> Doc
<> Doc
d Doc -> Doc -> Doc
<> String -> Doc
text String
"</em>"

-- | For when we add other things to reference like website, newspaper
renderCite :: BibFormatter -> Citation -> (Doc, Doc)
renderCite :: BibFormatter -> Citation -> (Doc, Doc)
renderCite BibFormatter
f (Cite String
e CitationKind
Book [CiteField]
cfs)      = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleBk    BibFormatter
f)  Doc -> Doc -> Doc
<> String -> Doc
text ([CiteField] -> String
sufxPrint [CiteField]
cfs))
renderCite BibFormatter
f (Cite String
e CitationKind
Article [CiteField]
cfs)   = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleArtcl BibFormatter
f)  Doc -> Doc -> Doc
<> String -> Doc
text ([CiteField] -> String
sufxPrint [CiteField]
cfs))
renderCite BibFormatter
f (Cite String
e CitationKind
MThesis [CiteField]
cfs)   = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleBk    BibFormatter
f)  Doc -> Doc -> Doc
<> String -> Doc
text ([CiteField] -> String
sufxPrint [CiteField]
cfs))
renderCite BibFormatter
f (Cite String
e CitationKind
PhDThesis [CiteField]
cfs) = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleBk    BibFormatter
f)  Doc -> Doc -> Doc
<> String -> Doc
text ([CiteField] -> String
sufxPrint [CiteField]
cfs))
renderCite BibFormatter
f (Cite String
e CitationKind
Misc [CiteField]
cfs)      = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleBk    BibFormatter
f))
renderCite BibFormatter
f (Cite String
e CitationKind
_ [CiteField]
cfs)         = (String -> Doc
text String
e, [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
cfs (BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleArtcl BibFormatter
f)) --FIXME: Properly render these later.

-- | Render fields to be used in the document.
renderF :: [CiteField] -> (StyleGuide -> (CiteField -> Doc)) -> Doc
renderF :: [CiteField] -> (StyleGuide -> CiteField -> Doc) -> Doc
renderF [CiteField]
fields StyleGuide -> CiteField -> Doc
styl = [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ StyleGuide -> CiteField -> Doc
styl StyleGuide
bibStyleH (CiteField -> Doc) -> [CiteField] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (CiteField -> CiteField -> Ordering) -> [CiteField] -> [CiteField]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy CiteField -> CiteField -> Ordering
compCiteField [CiteField]
fields

-- | Compares two cite fields.
compCiteField :: CiteField -> CiteField -> Ordering
compCiteField :: CiteField -> CiteField -> Ordering
compCiteField (Institution Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Institution Spec
_) = Ordering
GT
compCiteField (Organization Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Organization Spec
_) = Ordering
GT
compCiteField (Author     People
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Author     People
_) = Ordering
GT
compCiteField (Title      Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Title      Spec
_) = Ordering
GT
compCiteField (Series     Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Series     Spec
_) = Ordering
GT
compCiteField (BookTitle Spec
_) CiteField
_  = Ordering
LT
compCiteField CiteField
_ (BookTitle Spec
_)  = Ordering
GT
compCiteField (Editor     People
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Editor     People
_) = Ordering
GT
compCiteField (Journal    Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Journal    Spec
_) = Ordering
GT
compCiteField (Volume     Int
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Volume     Int
_) = Ordering
GT
compCiteField (Number     Int
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Number     Int
_) = Ordering
GT
compCiteField (Edition    Int
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Edition    Int
_) = Ordering
GT
compCiteField (HowPublished (Verb Spec
_)) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (HowPublished (Verb Spec
_)) = Ordering
GT
compCiteField (School     Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (School     Spec
_) = Ordering
GT
compCiteField (Address      Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Address      Spec
_) = Ordering
GT
compCiteField (Publisher  Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Publisher  Spec
_) = Ordering
GT
compCiteField (Month      Month
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Month      Month
_) = Ordering
GT
compCiteField (Year       Int
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Year       Int
_) = Ordering
GT
compCiteField (HowPublished (URL Spec
_)) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (HowPublished (URL Spec
_)) = Ordering
GT
compCiteField (Chapter    Int
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Chapter    Int
_) = Ordering
GT
compCiteField (Pages      [Int]
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Pages      [Int]
_) = Ordering
GT
compCiteField (Note       Spec
_) CiteField
_ = Ordering
LT
compCiteField CiteField
_ (Note       Spec
_) = Ordering
GT
compCiteField (Type       Spec
_) CiteField
_ = Ordering
LT

-- Config helpers --
-- | Renders citation as a book style.
useStyleBk :: BibFormatter -> StyleGuide -> (CiteField -> Doc)
useStyleBk :: BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleBk BibFormatter
f StyleGuide
MLA     = BibFormatter -> CiteField -> Doc
bookMLA BibFormatter
f
useStyleBk BibFormatter
f StyleGuide
APA     = BibFormatter -> CiteField -> Doc
bookAPA BibFormatter
f
useStyleBk BibFormatter
f StyleGuide
Chicago = BibFormatter -> CiteField -> Doc
bookChicago BibFormatter
f

-- | Renders citation as an article style.
useStyleArtcl :: BibFormatter -> StyleGuide -> (CiteField -> Doc)
useStyleArtcl :: BibFormatter -> StyleGuide -> CiteField -> Doc
useStyleArtcl BibFormatter
f StyleGuide
MLA     = BibFormatter -> CiteField -> Doc
artclMLA BibFormatter
f
useStyleArtcl BibFormatter
f StyleGuide
APA     = BibFormatter -> CiteField -> Doc
artclAPA BibFormatter
f
useStyleArtcl BibFormatter
f StyleGuide
Chicago = BibFormatter -> CiteField -> Doc
artclChicago BibFormatter
f

-- FIXME: move these show functions and use tags, combinators
-- | Cite books in MLA format.
bookMLA :: BibFormatter -> CiteField -> Doc
bookMLA :: BibFormatter -> CiteField -> Doc
bookMLA BibFormatter
f (Address   Spec
s) = BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s Doc -> Doc -> Doc
<> String -> Doc
text String
":"
bookMLA BibFormatter
_ (Edition   Int
s) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
s String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> Int -> String
sufxer Int
s String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> String
" ed."
bookMLA BibFormatter
f (Series    Spec
s) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Doc -> Doc
emph BibFormatter
f (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
f (Title     Spec
s) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Doc -> Doc
emph BibFormatter
f (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s --If there is a series or collection, this should be in quotes, not italics
bookMLA BibFormatter
_ (Volume    Int
s) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String
"vol. " String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> Int -> String
forall a. Show a => a -> String
show Int
s
bookMLA BibFormatter
f (Publisher Spec
s) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
f (Author    People
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f (People -> Spec
rendPeople' People
p)
bookMLA BibFormatter
_ (Year      Int
y) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
y
bookMLA BibFormatter
f (BookTitle Spec
s) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Doc -> Doc
emph BibFormatter
f (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
f (Journal   Spec
s) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Doc -> Doc
emph BibFormatter
f (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
_ (Pages   [Int
p]) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String
"pg. " String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> Int -> String
forall a. Show a => a -> String
show Int
p
bookMLA BibFormatter
_ (Pages     [Int]
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text String
"pp. " Doc -> Doc -> Doc
<> [Int] -> Doc
foldPages [Int]
p
bookMLA BibFormatter
f (Note      Spec
s) = BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
_ (Number    Int
n) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String
"no. " String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> Int -> String
forall a. Show a => a -> String
show Int
n)
bookMLA BibFormatter
f (School    Spec
s) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
f (HowPublished (Verb Spec
s))      = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
f (HowPublished (URL l :: Spec
l@(S String
s))) = Doc -> Doc
dot  (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f (Spec -> Doc) -> Spec -> Doc
forall a b. (a -> b) -> a -> b
$ LinkType -> String -> Spec -> Spec
Ref LinkType
External String
s Spec
l
bookMLA BibFormatter
f (HowPublished (URL Spec
s))       = Doc -> Doc
dot  (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
bookMLA BibFormatter
_ (Editor       People
p) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text String
"Edited by " Doc -> Doc -> Doc
<> People -> Doc
foldPeople People
p
bookMLA BibFormatter
_ (Chapter      Int
_) = String -> Doc
text String
""
bookMLA BibFormatter
f (Institution  Spec
i) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
i
bookMLA BibFormatter
f (Organization Spec
i) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
i
bookMLA BibFormatter
_ (Month        Month
m) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ Month -> String
forall a. Show a => a -> String
show Month
m
bookMLA BibFormatter
f (Type         Spec
t) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
t

-- | Cite books in APA format.
bookAPA :: BibFormatter -> CiteField -> Doc --FIXME: year needs to come after author in APA
bookAPA :: BibFormatter -> CiteField -> Doc
bookAPA BibFormatter
f (Author   People
p) = BibFormatter -> Spec -> Doc
spec BibFormatter
f ((Person -> String) -> People -> Spec
rendPeople Person -> String
rendPersLFM' People
p) --L.APA uses initals rather than full name
bookAPA BibFormatter
_ (Year     Int
y) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. CanTextWrap a => a -> a
paren (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
y --APA puts "()" around the year
bookAPA BibFormatter
_ (Pages    [Int]
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Int] -> Doc
foldPages [Int]
p
bookAPA BibFormatter
_ (Editor   People
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ People -> Doc
foldPeople People
p Doc -> Doc -> Doc
<> String -> Doc
text String
" (Ed.)"
bookAPA BibFormatter
f CiteField
i = BibFormatter -> CiteField -> Doc
bookMLA BibFormatter
f CiteField
i --Most items are rendered the same as MLA

-- | Cite books in Chicago format.
bookChicago :: BibFormatter -> CiteField -> Doc
bookChicago :: BibFormatter -> CiteField -> Doc
bookChicago BibFormatter
f (Author   People
p) = BibFormatter -> Spec -> Doc
spec BibFormatter
f ((Person -> String) -> People -> Spec
rendPeople Person -> String
rendPersLFM'' People
p) -- APA uses middle initals rather than full name
bookChicago BibFormatter
_ (Pages    [Int]
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Int] -> Doc
foldPages [Int]
p
bookChicago BibFormatter
_ (Editor   People
p) = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ People -> Doc
foldPeople People
p Doc -> Doc -> Doc
<> String -> Doc
text (People -> String -> String
toPlural People
p String
" ed")
bookChicago BibFormatter
f CiteField
i = BibFormatter -> CiteField -> Doc
bookMLA BibFormatter
f CiteField
i --Most items are rendered the same as MLA

-- for article renderings
-- | Cite articles in MLA format.
artclMLA :: BibFormatter -> CiteField -> Doc
artclMLA :: BibFormatter -> CiteField -> Doc
artclMLA BibFormatter
f (Title Spec
s) = Doc -> Doc
forall a. CanTextWrap a => a -> a
dquote (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
artclMLA BibFormatter
f CiteField
i         = BibFormatter -> CiteField -> Doc
bookMLA BibFormatter
f CiteField
i

-- | Cite articles in APA format.
artclAPA :: BibFormatter -> CiteField -> Doc
artclAPA :: BibFormatter -> CiteField -> Doc
artclAPA BibFormatter
f (Title  Spec
s)  = Doc -> Doc
dot (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ BibFormatter -> Spec -> Doc
spec BibFormatter
f Spec
s
artclAPA BibFormatter
_ (Volume Int
n)  = Doc -> Doc
em (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
n
artclAPA BibFormatter
_ (Number  Int
n) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. CanTextWrap a => a -> a
paren (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
n
artclAPA BibFormatter
f CiteField
i           = BibFormatter -> CiteField -> Doc
bookAPA BibFormatter
f CiteField
i

-- | Cite articles in Chicago format.
artclChicago :: BibFormatter -> CiteField -> Doc
artclChicago :: BibFormatter -> CiteField -> Doc
artclChicago BibFormatter
f i :: CiteField
i@(Title    Spec
_) = BibFormatter -> CiteField -> Doc
artclMLA BibFormatter
f CiteField
i
artclChicago BibFormatter
_ (Volume     Int
n) = Doc -> Doc
comm (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
n
artclChicago BibFormatter
_ (Number      Int
n) = String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String
"no. " String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> Int -> String
forall a. Show a => a -> String
show Int
n
artclChicago BibFormatter
f i :: CiteField
i@(Year     Int
_) = BibFormatter -> CiteField -> Doc
bookAPA BibFormatter
f CiteField
i
artclChicago BibFormatter
f CiteField
i = BibFormatter -> CiteField -> Doc
bookChicago BibFormatter
f CiteField
i

-- PEOPLE RENDERING --
-- | Render a list of people (after applying a given function).
rendPeople :: (Person -> String) -> People -> Spec
rendPeople :: (Person -> String) -> People -> Spec
rendPeople Person -> String
_ []  = String -> Spec
S String
"N.a." -- "No authors given"
rendPeople Person -> String
f People
people = String -> Spec
S (String -> Spec) -> ([String] -> String) -> [String] -> Spec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. (IsString a, Semigroup a) => [a] -> a
foldlList ([String] -> Spec) -> [String] -> Spec
forall a b. (a -> b) -> a -> b
$ Person -> String
f (Person -> String) -> People -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> People
people --foldlList is in drasil-utils

-- | Render a list of people (of form FirstName LastName).
rendPeople' :: People -> Spec
rendPeople' :: People -> Spec
rendPeople' []  = String -> Spec
S String
"N.a." -- "No authors given"
rendPeople' People
people = String -> Spec
S (String -> Spec) -> ([String] -> String) -> [String] -> Spec
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. (IsString a, Semigroup a) => [a] -> a
foldlList ([String] -> Spec) -> [String] -> Spec
forall a b. (a -> b) -> a -> b
$ (Person -> String) -> People -> [String]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Person -> String
rendPersLFM (People -> People
forall a. HasCallStack => [a] -> [a]
init People
people) [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
P.<>  [Person -> String
rendPersL (People -> Person
forall a. HasCallStack => [a] -> a
last People
people)]

-- | Organize a list of pages.
foldPages :: [Int] -> Doc
foldPages :: [Int] -> Doc
foldPages = String -> Doc
text (String -> Doc) -> ([Int] -> String) -> [Int] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. (IsString a, Semigroup a) => [a] -> a
foldlList ([String] -> String) -> ([Int] -> [String]) -> [Int] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [Int] -> [String]
numList String
"&ndash;"

-- | Organize a list of people.
foldPeople :: People -> Doc
foldPeople :: People -> Doc
foldPeople People
p = String -> Doc
text (String -> Doc) -> ([String] -> String) -> [String] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. (IsString a, Semigroup a) => [a] -> a
foldlList ([String] -> Doc) -> [String] -> Doc
forall a b. (a -> b) -> a -> b
$ Person -> String
forall n. HasName n => n -> String
fullName (Person -> String) -> People -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> People
p

-- | Renders a person's last name.
rendPersL :: Person -> String
rendPersL :: Person -> String
rendPersL =
  (\String
n -> (if Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
n) Bool -> Bool -> Bool
&& String -> Char
forall a. HasCallStack => [a] -> a
last String
n Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.' then String -> String
forall a. HasCallStack => [a] -> [a]
init else String -> String
forall a. a -> a
id) String
n) (String -> String) -> (Person -> String) -> Person -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Person -> String
rendPersLFM

-- | adds an 's' if there is more than one person in a list.
toPlural :: People -> String -> String
toPlural :: People -> String -> String
toPlural (Person
_:People
_) String
str = String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
P.<> String
"s"
toPlural People
_     String
str = String
str