module Text.CSL.Style where
import Data.Generics
data Style
= Style
{ styleClass :: String
, styleInfo :: Maybe CSInfo
, styleLang :: String
, styleLocale :: String
, csTerms :: [TermMap]
, csMacros :: [MacroMap]
, citation :: Citation
, biblio :: Maybe Bibliography
} deriving ( Show, Typeable, Data )
type TermMap
= ((String,Form),(String,String))
type MacroMap
= (String,[Element])
data Citation
= Citation
{ citOptions :: [Option]
, citSort :: [Sort]
, citLayout :: Layout
} deriving ( Show, Typeable, Data )
data Bibliography
= Bibliography
{ bibOptions :: [Option]
, bibSort :: [Sort]
, bibLayout :: Layout
} deriving ( Show, Typeable, Data )
type Option = (String,String)
data Layout
= Layout
{ layFormat :: Formatting
, layDelim :: Delimiter
, elements :: [Element]
} deriving ( Show, Typeable, Data )
data Element
= Choose IfThen [IfThen] [Element]
| Macro String Form Formatting
| Const String Formatting
| PointLocator String Form Formatting
| Variable [String] Form Formatting Delimiter
| Term String Form Formatting Bool Bool
| Label String Form Formatting Bool Bool
| Number String NumericForm Formatting
| ShortNames [String] Formatting Delimiter
| Names [String] [Name] Formatting Delimiter [Element]
| Substitute [Element]
| Group Formatting Delimiter String [Element]
| Date [String] Formatting Delimiter [DatePart]
deriving ( Show, Eq, Typeable, Data )
data IfThen
= IfThen Condition Match [Element]
deriving ( Eq, Show, Typeable, Data )
data Condition
= Condition
{ isType :: [String]
, isSet :: [String]
, isNumeric :: [String]
, isDate :: [String]
, isPosition :: [String]
, disambiguation :: [String]
, isLocator :: [String]
}
deriving ( Eq, Show, Typeable, Data )
type Delimiter
= String
data Match
= Any
| All
| None
deriving ( Show, Read, Eq, Typeable, Data )
match :: Match -> [Bool] -> Bool
match All = and
match Any = or
match None = and . map not
data DatePart
= DatePart String String Formatting
deriving ( Show, Eq, Typeable, Data )
defaultDate :: [DatePart]
defaultDate
= [ DatePart "year" "" emptyFormatting
, DatePart "month" "" emptyFormatting
, DatePart "day" "" emptyFormatting]
data Sort
= SortVariable String Sorting
| SortMacro String Sorting
deriving ( Eq, Show, Typeable, Data )
data Sorting
= Ascending String
| Descending String
deriving ( Eq, Read, Typeable, Data )
instance Show Sorting where
show (Ascending s) = s
show (Descending s) = s
instance Ord Sorting where
compare (Ascending a) (Ascending b) = compare a b
compare (Descending a) (Descending b) = compare b a
compare _ _ = EQ
data Form
= Long
| Verb
| Short
| VerbShort
| Symbol
deriving ( Eq, Show, Read, Typeable, Data )
data NumericForm
= Numeric
| Ordinal
| Roman
deriving ( Eq, Show, Read, Typeable, Data )
data Name
= Name Form Formatting NameFormatting Delimiter
| NameLabel Form Formatting Bool Bool
deriving ( Eq, Show, Typeable, Data )
isName :: Name -> Bool
isName x = case x of Name {} -> True; _ -> False
data NameFormatting
= NameFormatting
{ andConnector :: String
, delimiterPrecedesLast :: String
, nameAsSortOrder :: String
, sortSeparator :: String
, initializeWith :: String
} deriving ( Eq, Show, Typeable, Data )
defaultNameFormatting :: NameFormatting
defaultNameFormatting
= NameFormatting
{ andConnector = "text"
, delimiterPrecedesLast = ""
, nameAsSortOrder = ""
, sortSeparator = ""
, initializeWith = ""
}
data Formatting
= Formatting
{ prefix :: String
, suffix :: String
, fontFamily :: String
, fontStyle :: String
, fontVariant :: String
, fontWeight :: String
, textDecoration :: String
, verticalAlign :: String
, textCase :: String
, display :: String
, quotes :: Bool
} deriving ( Eq, Ord, Read, Show, Typeable, Data )
emptyFormatting :: Formatting
emptyFormatting
= Formatting [] [] [] [] [] [] [] [] [] [] False
data CSInfo
= CSInfo
{ csiTitle :: String
, csiAuthor :: CSAuthor
, csiCategories :: [CSCategory]
, csiId :: String
, csiUpdated :: String
} deriving ( Show, Read, Typeable, Data )
data CSAuthor = CSAuthor String String String deriving ( Show, Read, Eq, Typeable, Data )
data CSCategory = CSCategory String String String deriving ( Show, Read, Eq, Typeable, Data )
data FormattedOutput
= FO String Formatting [FormattedOutput]
| Delimiter String
deriving ( Eq, Show )
data Output
= OStr String Formatting
| OName String [String] Formatting
| OYear String String Formatting
| OCitNum Int Formatting
| Output [Output] Formatting
| OContrib String [Output] [[Output]]
| ODel String
deriving ( Eq, Ord, Show, Typeable, Data )
data CitationGroup = CG Formatting String [Output] deriving ( Show, Eq, Typeable, Data )
data BiblioData
= BD
{ citations :: [[FormattedOutput]]
, bibliography :: [[FormattedOutput]]
} deriving ( Show )
data CiteData
= CD
{ key :: String
, collision :: [Output]
, disambData :: [[Output]]
, disambed :: [Output]
, citYear :: String
} deriving ( Show, Typeable, Data )
instance Eq CiteData where
(==) (CD ka ca _ _ _)
(CD kb cb _ _ _) = ka == kb && ca == cb
formatOutput :: Output -> FormattedOutput
formatOutput o
| ODel s <- o = Delimiter s
| OStr s f <- o = FO s f []
| OName s _ f <- o = FO s f []
| OYear s _ f <- o = FO s f []
| Output os f <- o = FO "" f (format os)
| OContrib _ s _ <- o = FO "" emptyFormatting (format s)
| OCitNum i f <- o = FO (show i) f []
| otherwise = FO "" emptyFormatting []
where
format = map formatOutput
mapGroupOutput :: (Output -> [a]) -> CitationGroup -> [a]
mapGroupOutput f (CG _ _ os) = concatMap f os
proc :: (Typeable a, Data b) => (a -> a) -> b -> b
proc f = everywhere (mkT f)
query :: (Typeable a, Data b) => (a -> [c]) -> b -> [c]
query f = everything (++) ([] `mkQ` f)
rmGivenNames :: Output -> Output
rmGivenNames o
| OName s _ f <- o = OName s [] f
| otherwise = o
rmContribs :: Output -> Output
rmContribs o
| OContrib s _ _ <- o = OContrib s [] []
| otherwise = o
addGivenNames :: [Output] -> [Output]
addGivenNames
= reverse . addGN True . reverse
where
addGN _ [] = []
addGN b (o:os)
| OName _ xs f <- o
, xs /= [] = if b then OName (head xs) (tail xs) f : addGN False os else o:os
| otherwise = o : addGN b os
addYearSuffix :: Output -> Output
addYearSuffix o
| OYear y s f <- o = OYear (y ++ s) s f
| otherwise = o