{-# LANGUAGE OverloadedStrings #-}

module Language.Drasil.HTML.Citation (
  printBib
) where

import Data.Text (Text)
import qualified Data.Text as T (pack, show)
import Data.List (sortBy)
import Utils.Drasil (foldlList)

import Language.Drasil (People, Person, fullName, rendPersLFM, rendPersLFM',
  rendPersLFM'', numList)
import Language.Drasil.Config (StyleGuide(..), bibStyleH)
import Language.Drasil.Document (CitationKind(..))
import Drasil.Data.Formats.HTML (HTMLBody(..), DItem(..), bold_, emphasis_,
  rawText, rawText', id_, class_)

import Drasil.Printers.Common (paren)
import Language.Drasil.HTML.Spec (specToHTML, printSpec)
import Language.Drasil.Printing.AST (Spec(S))
import Language.Drasil.Printing.Citation (CiteField(..), HP(..), Citation(..), BibRef)
import Language.Drasil.Printing.Helpers (sufxer, sufxPrint)

-- | Internal: Wrap an HTMLBody with text on both sides.
wrapBodyWText :: Text -> Text -> HTMLBody -> [HTMLBody]
wrapBodyWText :: Text -> Text -> HTMLBody -> [HTMLBody]
wrapBodyWText Text
l Text
r HTMLBody
b = [Text -> HTMLBody
RawText Text
l, HTMLBody
b, Text -> HTMLBody
RawText Text
r]

-- | Internal: Place an 'HTMLBody' in brackets.
sqBrak :: HTMLBody -> [HTMLBody]
sqBrak :: HTMLBody -> [HTMLBody]
sqBrak = Text -> Text -> HTMLBody -> [HTMLBody]
wrapBodyWText Text
"[" Text
"]"

-- | Makes a bibliography for the document.
printBib :: BibRef -> HTMLBody
printBib :: BibRef -> HTMLBody
printBib BibRef
bib =
  [Attr] -> [DItem] -> HTMLBody
DescriptionList [[Text] -> Attr
class_ [Text
"reference-list"]] ((Citation -> [DItem]) -> BibRef -> [DItem]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Citation -> [DItem]
renderCitation BibRef
bib)
  where
    renderCitation :: Citation -> [DItem]
    renderCitation :: Citation -> [DItem]
renderCitation cite :: Citation
cite@(Cite String
e CitationKind
_ [CiteField]
_) =
      let ([HTMLBody]
termDoc, [HTMLBody]
detailsDoc) = Citation -> ([HTMLBody], [HTMLBody])
renderCite Citation
cite
       in [ [Attr] -> [HTMLBody] -> DItem
DTerm [Text -> Attr
id_ (Text -> Attr) -> Text -> Attr
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
e] ([HTMLBody] -> DItem) -> [HTMLBody] -> DItem
forall a b. (a -> b) -> a -> b
$ HTMLBody -> [HTMLBody]
sqBrak (HTMLBody -> [HTMLBody]) -> HTMLBody -> [HTMLBody]
forall a b. (a -> b) -> a -> b
$ [HTMLBody] -> HTMLBody
bold_ [HTMLBody]
termDoc
          , [Attr] -> [HTMLBody] -> DItem
DDetails [] [HTMLBody]
detailsDoc
          ]

-- | Internal: For when we add other things to reference like website, newspaper.
renderCite :: Citation -> ([HTMLBody], [HTMLBody])
renderCite :: Citation -> ([HTMLBody], [HTMLBody])
renderCite (Cite String
e CitationKind
kind [CiteField]
cfs) = ([String -> HTMLBody
rawText' String
e], [CiteField]
-> (StyleGuide -> CiteField -> [HTMLBody]) -> [HTMLBody]
renderF [CiteField]
cfs StyleGuide -> CiteField -> [HTMLBody]
style [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody]
sufx)
  where
    (StyleGuide -> CiteField -> [HTMLBody]
style, [HTMLBody]
sufx) = case CitationKind
kind of
      CitationKind
Article   -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleArtcl, [String -> HTMLBody
rawText' (String -> HTMLBody) -> String -> HTMLBody
forall a b. (a -> b) -> a -> b
$ [CiteField] -> String
sufxPrint [CiteField]
cfs])
      CitationKind
Book      -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleBk,    [String -> HTMLBody
rawText' (String -> HTMLBody) -> String -> HTMLBody
forall a b. (a -> b) -> a -> b
$ [CiteField] -> String
sufxPrint [CiteField]
cfs])
      CitationKind
MThesis   -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleBk,    [String -> HTMLBody
rawText' (String -> HTMLBody) -> String -> HTMLBody
forall a b. (a -> b) -> a -> b
$ [CiteField] -> String
sufxPrint [CiteField]
cfs])
      CitationKind
PhDThesis -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleBk,    [String -> HTMLBody
rawText' (String -> HTMLBody) -> String -> HTMLBody
forall a b. (a -> b) -> a -> b
$ [CiteField] -> String
sufxPrint [CiteField]
cfs])
      CitationKind
Misc      -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleBk,    [])
      CitationKind
_         -> (StyleGuide -> CiteField -> [HTMLBody]
useStyleArtcl, [])

-- | Internal: Generates fields to be used in the document.
renderF :: [CiteField] -> (StyleGuide -> (CiteField -> [HTMLBody])) -> [HTMLBody]
renderF :: [CiteField]
-> (StyleGuide -> CiteField -> [HTMLBody]) -> [HTMLBody]
renderF [CiteField]
fields StyleGuide -> CiteField -> [HTMLBody]
styl = (CiteField -> [HTMLBody]) -> [CiteField] -> [HTMLBody]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (StyleGuide -> CiteField -> [HTMLBody]
styl StyleGuide
bibStyleH) ((CiteField -> CiteField -> Ordering) -> [CiteField] -> [CiteField]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy CiteField -> CiteField -> Ordering
compCiteField [CiteField]
fields)

-- | Internal: 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

-- | Internal: Citation formatting constants.
colon, period, comma, vol, pg, pp, no, ed, editedBy :: HTMLBody
colon :: HTMLBody
colon = HTMLBody
": "
period :: HTMLBody
period = HTMLBody
". "
comma :: HTMLBody
comma = HTMLBody
", "
vol :: HTMLBody
vol = HTMLBody
"vol. "
pg :: HTMLBody
pg = HTMLBody
"pg. "
pp :: HTMLBody
pp = HTMLBody
"pp. "
no :: HTMLBody
no = HTMLBody
"no. "
ed :: HTMLBody
ed = HTMLBody
" ed., "
editedBy :: HTMLBody
editedBy = HTMLBody
"Edited by "

-- | Internal: Generates citation as a book style.
useStyleBk :: StyleGuide -> (CiteField -> [HTMLBody])
useStyleBk :: StyleGuide -> CiteField -> [HTMLBody]
useStyleBk StyleGuide
MLA     = CiteField -> [HTMLBody]
bookMLA
useStyleBk StyleGuide
APA     = CiteField -> [HTMLBody]
bookAPA
useStyleBk StyleGuide
Chicago = CiteField -> [HTMLBody]
bookChicago

-- | Internal: Generates citation as an article style.
useStyleArtcl :: StyleGuide -> (CiteField -> [HTMLBody])
useStyleArtcl :: StyleGuide -> CiteField -> [HTMLBody]
useStyleArtcl StyleGuide
MLA     = CiteField -> [HTMLBody]
artclMLA
useStyleArtcl StyleGuide
APA     = CiteField -> [HTMLBody]
artclAPA
useStyleArtcl StyleGuide
Chicago = CiteField -> [HTMLBody]
artclChicago

-- | Internal: Cite books in MLA format.
bookMLA :: CiteField -> [HTMLBody]
bookMLA :: CiteField -> [HTMLBody]
bookMLA (Address   Spec
s) = Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
colon]
bookMLA (Edition   Int
s) = [Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
s, String -> HTMLBody
rawText' (String -> HTMLBody) -> String -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> String
sufxer Int
s, HTMLBody
ed]
bookMLA (Series    Spec
s) = [[HTMLBody] -> HTMLBody
emphasis_ (Spec -> [HTMLBody]
specToHTML Spec
s), HTMLBody
period]
bookMLA (Title     Spec
s) = [[HTMLBody] -> HTMLBody
emphasis_ (Spec -> [HTMLBody]
specToHTML Spec
s), HTMLBody
period] --If there is a series or collection, this should be in quotes, not italics
bookMLA (Volume    Int
s) = [HTMLBody
vol, Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
s, HTMLBody
comma]
bookMLA (Publisher Spec
s) = Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]
bookMLA (Author    People
p) = Spec -> [HTMLBody]
specToHTML (People -> Spec
rendPeople' People
p) [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
period]
bookMLA (Year      Int
y) = [Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
y, HTMLBody
period]
bookMLA (BookTitle Spec
s) = [[HTMLBody] -> HTMLBody
emphasis_ (Spec -> [HTMLBody]
specToHTML Spec
s), HTMLBody
period]
bookMLA (Journal   Spec
s) = [[HTMLBody] -> HTMLBody
emphasis_ (Spec -> [HTMLBody]
specToHTML Spec
s), HTMLBody
comma]
bookMLA (Pages   [Int
p]) = [HTMLBody
pg, Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
p, HTMLBody
period]
bookMLA (Pages     [Int]
p) = [HTMLBody
pp, [Int] -> HTMLBody
foldPages [Int]
p, HTMLBody
period]
bookMLA (Note      Spec
s) = Spec -> [HTMLBody]
specToHTML Spec
s
bookMLA (Number    Int
n) = [HTMLBody
no, Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
n, HTMLBody
comma]
bookMLA (School    Spec
s) = Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]
bookMLA (HowPublished (Verb Spec
s)) = Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]
bookMLA (HowPublished (URL Spec
s)) = [Text -> [Attr] -> [HTMLBody] -> HTMLBody
Anchor (Spec -> Text
printSpec Spec
s) [] (Spec -> [HTMLBody]
specToHTML Spec
s), HTMLBody
period]
bookMLA (Editor       People
p) = [HTMLBody
editedBy, People -> HTMLBody
foldPeople People
p, HTMLBody
comma]
bookMLA (Chapter      Int
_) = []
bookMLA (Institution  Spec
i) = Spec -> [HTMLBody]
specToHTML Spec
i [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]
bookMLA (Organization Spec
i) = Spec -> [HTMLBody]
specToHTML Spec
i [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]
bookMLA (Month        Month
m) = [String -> HTMLBody
rawText' (Month -> String
forall a. Show a => a -> String
show Month
m), HTMLBody
comma]
bookMLA (Type         Spec
t) = Spec -> [HTMLBody]
specToHTML Spec
t [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
comma]

-- | Internal: Cite books in APA format.
bookAPA :: CiteField -> [HTMLBody] -- FIXME: year needs to come after author in APA
bookAPA :: CiteField -> [HTMLBody]
bookAPA (Author   People
p) = Spec -> [HTMLBody]
specToHTML ((Person -> String) -> People -> Spec
rendPeople Person -> String
rendPersLFM' People
p) --L.APA uses initials rather than full name
bookAPA (Year     Int
y) = [Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Text -> Text
forall a. CanTextWrap a => a -> a
paren (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
y, HTMLBody
period] --APA puts "()" around the year
bookAPA (Pages    [Int]
p) = [[Int] -> HTMLBody
foldPages [Int]
p, HTMLBody
period]
bookAPA (Editor   People
p) = [People -> HTMLBody
foldPeople People
p, HTMLBody
" (Ed.)", HTMLBody
period]
bookAPA CiteField
i = CiteField -> [HTMLBody]
bookMLA CiteField
i --Most items are rendered the same as MLA

-- | Internal: Cite books in Chicago format.
bookChicago :: CiteField -> [HTMLBody]
bookChicago :: CiteField -> [HTMLBody]
bookChicago (Author   People
p) = Spec -> [HTMLBody]
specToHTML ((Person -> String) -> People -> Spec
rendPeople Person -> String
rendPersLFM'' People
p) -- APA uses middle initials rather than full name
bookChicago (Pages    [Int]
p) = [[Int] -> HTMLBody
foldPages [Int]
p, HTMLBody
period]
bookChicago (Editor   People
p) = [People -> HTMLBody
foldPeople People
p, Text -> HTMLBody
RawText (People -> Text -> Text
toPlural People
p Text
" ed"), HTMLBody
period]
bookChicago CiteField
i = CiteField -> [HTMLBody]
bookMLA CiteField
i --Most items are rendered the same as MLA

-- for article renderings

-- | Internal: Cite articles in MLA format.
artclMLA :: CiteField -> [HTMLBody]
artclMLA :: CiteField -> [HTMLBody]
artclMLA (Title Spec
s) = [HTMLBody
"\""] [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
".\" "]
artclMLA CiteField
i         = CiteField -> [HTMLBody]
bookMLA CiteField
i

-- | Internal: Cite articles in APA format.
artclAPA :: CiteField -> [HTMLBody]
artclAPA :: CiteField -> [HTMLBody]
artclAPA (Title  Spec
s)  = Spec -> [HTMLBody]
specToHTML Spec
s [HTMLBody] -> [HTMLBody] -> [HTMLBody]
forall a. Semigroup a => a -> a -> a
<> [HTMLBody
". "]
artclAPA (Volume Int
n)  = [[HTMLBody] -> HTMLBody
emphasis_ [Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
n]]
artclAPA (Number  Int
n) = [HTMLBody
", ", Text -> HTMLBody
RawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Text -> Text
forall a. CanTextWrap a => a -> a
paren (Int -> Text
forall a. Show a => a -> Text
T.show Int
n), HTMLBody
" "]
artclAPA CiteField
i           = CiteField -> [HTMLBody]
bookAPA CiteField
i

-- | Internal: Cite articles in Chicago format.
artclChicago :: CiteField -> [HTMLBody]
artclChicago :: CiteField -> [HTMLBody]
artclChicago i :: CiteField
i@(Title    Spec
_)  = CiteField -> [HTMLBody]
artclMLA CiteField
i
artclChicago (Volume     Int
n)  = [Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
n, HTMLBody
comma]
artclChicago (Number      Int
n) = [HTMLBody
no, Text -> HTMLBody
rawText (Text -> HTMLBody) -> Text -> HTMLBody
forall a b. (a -> b) -> a -> b
$ Int -> Text
forall a. Show a => a -> Text
T.show Int
n]
artclChicago i :: CiteField
i@(Year     Int
_)  = CiteField -> [HTMLBody]
bookAPA CiteField
i
artclChicago CiteField
i = CiteField -> [HTMLBody]
bookChicago CiteField
i

-- PEOPLE RENDERING --

-- | Internal: Generate 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

-- | Internal: Generate 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
<> [Person -> String
rendPersL (People -> Person
forall a. HasCallStack => [a] -> a
last People
people)]

-- | Internal: Organize a list of pages.
foldPages :: [Int] -> HTMLBody
foldPages :: [Int] -> HTMLBody
foldPages = String -> HTMLBody
rawText' (String -> HTMLBody) -> ([Int] -> String) -> [Int] -> HTMLBody
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
"–"

-- | Internal: Organize a list of people.
foldPeople :: People -> HTMLBody
foldPeople :: People -> HTMLBody
foldPeople People
p = String -> HTMLBody
rawText' (String -> HTMLBody)
-> ([String] -> String) -> [String] -> HTMLBody
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. (IsString a, Semigroup a) => [a] -> a
foldlList ([String] -> HTMLBody) -> [String] -> HTMLBody
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

-- | Internal: Generate 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

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