module Language.Drasil.Data.Citation (
CiteField(..), HP(..), CitationKind(..),
HasFields(..),
author, editor,
address, bookTitle, howPublished, howPublishedU, institution, journal, note,
organization, publisher, school, series, title, typeField,
chapter, edition, number, volume, year,
pages,
month,
compareAuthYearTitle
) where
import Control.Lens (Lens', (^.))
import Data.Maybe (mapMaybe)
import Language.Drasil.People (People, comparePeople)
import Language.Drasil.Data.Date (Month(..))
data CiteField = Address String
| Author People
| BookTitle String
| Chapter Int
| Edition Int
| Editor People
| HowPublished HP
| Institution String
| Journal String
| Month Month
| Note String
| Number Int
| Organization String
| Pages [Int]
| Publisher String
| School String
| Series String
| Title String
| Type String
| Volume Int
| Year Int
class HasFields c where
getFields :: Lens' c [CiteField]
data HP = URL String
| Verb String
data CitationKind = Article
| Book
| Booklet
| InBook
| InCollection
| InProceedings
| Manual
| MThesis
| Misc
| PhDThesis
| Proceedings
| TechReport
| Unpublished
author, editor :: People -> CiteField
author :: People -> CiteField
author = People -> CiteField
Author
editor :: People -> CiteField
editor = People -> CiteField
Editor
address, bookTitle, institution, journal,
howPublished, howPublishedU, note, organization, publisher, school, series, title,
typeField :: String -> CiteField
address :: String -> CiteField
address = String -> CiteField
Address
bookTitle :: String -> CiteField
bookTitle = String -> CiteField
BookTitle
howPublished :: String -> CiteField
howPublished = HP -> CiteField
HowPublished (HP -> CiteField) -> (String -> HP) -> String -> CiteField
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HP
Verb
howPublishedU :: String -> CiteField
howPublishedU = HP -> CiteField
HowPublished (HP -> CiteField) -> (String -> HP) -> String -> CiteField
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HP
URL
institution :: String -> CiteField
institution = String -> CiteField
Institution
journal :: String -> CiteField
journal = String -> CiteField
Journal
note :: String -> CiteField
note = String -> CiteField
Note
organization :: String -> CiteField
organization = String -> CiteField
Organization
publisher :: String -> CiteField
publisher = String -> CiteField
Publisher
school :: String -> CiteField
school = String -> CiteField
School
series :: String -> CiteField
series = String -> CiteField
Series
title :: String -> CiteField
title = String -> CiteField
Title
typeField :: String -> CiteField
typeField = String -> CiteField
Type
chapter, edition, number, volume, year :: Int -> CiteField
chapter :: Int -> CiteField
chapter = Int -> CiteField
Chapter
edition :: Int -> CiteField
edition = Int -> CiteField
Edition
number :: Int -> CiteField
number = Int -> CiteField
Number
volume :: Int -> CiteField
volume = Int -> CiteField
Volume
year :: Int -> CiteField
year = Int -> CiteField
Year
pages :: [Int] -> CiteField
pages :: [Int] -> CiteField
pages = [Int] -> CiteField
Pages
month :: Month -> CiteField
month :: Month -> CiteField
month = Month -> CiteField
Month
compareAuthYearTitle :: HasFields c => c -> c -> Ordering
compareAuthYearTitle :: forall c. HasFields c => c -> c -> Ordering
compareAuthYearTitle c
c1 c
c2
| Ordering
cp Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
EQ = Ordering
cp
| Int
y1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
y2 = Int
y1 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Int
y2
| Bool
otherwise = String
t1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
t2
where
(People
a1, Int
y1, String
t1) = c -> (People, Int, String)
forall c. HasFields c => c -> (People, Int, String)
getAuthorYearTitle c
c1
(People
a2, Int
y2, String
t2) = c -> (People, Int, String)
forall c. HasFields c => c -> (People, Int, String)
getAuthorYearTitle c
c2
cp :: Ordering
cp = People -> People -> Ordering
comparePeople People
a1 People
a2
getAuthorYearTitle :: HasFields c => c -> (People, Int, String)
getAuthorYearTitle :: forall c. HasFields c => c -> (People, Int, String)
getAuthorYearTitle c
c = (People
a, Int
y, String
t)
where
fs :: [CiteField]
fs = c
c c -> Getting [CiteField] c [CiteField] -> [CiteField]
forall s a. s -> Getting a s a -> a
^. Getting [CiteField] c [CiteField]
forall c. HasFields c => Lens' c [CiteField]
Lens' c [CiteField]
getFields
justAuthor :: CiteField -> Maybe People
justAuthor (Author People
x) = People -> Maybe People
forall a. a -> Maybe a
Just People
x
justAuthor CiteField
_ = Maybe People
forall a. Maybe a
Nothing
as :: [People]
as = (CiteField -> Maybe People) -> [CiteField] -> [People]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe CiteField -> Maybe People
justAuthor [CiteField]
fs
a :: People
a = if Bool -> Bool
not ([People] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [People]
as) then [People] -> People
forall a. HasCallStack => [a] -> a
head [People]
as else String -> People
forall a. HasCallStack => String -> a
error String
"No author found"
justYear :: CiteField -> Maybe Int
justYear (Year Int
x) = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
x
justYear CiteField
_ = Maybe Int
forall a. Maybe a
Nothing
ys :: [Int]
ys = (CiteField -> Maybe Int) -> [CiteField] -> [Int]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe CiteField -> Maybe Int
justYear [CiteField]
fs
y :: Int
y = if Bool -> Bool
not ([Int] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
ys) then [Int] -> Int
forall a. HasCallStack => [a] -> a
head [Int]
ys else String -> Int
forall a. HasCallStack => String -> a
error String
"No year found"
justTitle :: CiteField -> Maybe String
justTitle (Title String
x) = String -> Maybe String
forall a. a -> Maybe a
Just String
x
justTitle CiteField
_ = Maybe String
forall a. Maybe a
Nothing
ts :: [String]
ts = (CiteField -> Maybe String) -> [CiteField] -> [String]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe CiteField -> Maybe String
justTitle [CiteField]
fs
t :: String
t = if Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
ts) then [String] -> String
forall a. HasCallStack => [a] -> a
head [String]
ts else String -> String
forall a. HasCallStack => String -> a
error String
"No title found"