module Codec.Epub.Data.Metadata
( Metadata (..)
, Identifier (..)
, Title (..)
, Creator (..)
, Date (..)
, Description (..)
, Refinement (..)
, emptyMetadata
, refineIdentifier
, refineTitle
, getModified
, refineCreator
)
where
import Control.Monad ( mplus )
import Data.List ( find )
data Refinement = Refinement
{ refId :: String
, refProp :: String
, refScheme :: String
, refText :: String
}
findByIdProp :: String -> String -> [Refinement] -> Maybe Refinement
findByIdProp i prop = find (\r -> refId r == i && refProp r == prop)
data Identifier = Identifier
{ idId :: Maybe String
, idType :: Maybe String
, idScheme :: Maybe String
, idText :: String
}
deriving (Eq, Show)
refineIdentifier :: [Refinement] -> Identifier -> Identifier
refineIdentifier refinements ident = assignScheme . assignType $ ident
where
meta = findByIdProp (maybe "" id $ idId ident)
"identifier-type" refinements
assignType ident' = ident' { idType = refText `fmap` meta }
assignScheme ident' =
let existingScheme = idScheme ident'
in ident' { idScheme = existingScheme `mplus`
(refScheme `fmap` meta) }
data Title = Title
{ titleLang :: Maybe String
, titleType :: Maybe String
, titleSeq :: Maybe Int
, titleText :: String
}
deriving (Eq, Show)
refineTitle :: [Refinement] -> (String, Title) -> Title
refineTitle refinements (elid, title) = assignSeq . assignType $ title
where
assignType title' =
let newTy = refText `fmap`
findByIdProp elid "title-type" refinements
in title' { titleType = newTy }
assignSeq title' =
let sq = maybe Nothing (Just . read . refText) $
findByIdProp elid "display-seq" refinements
in title' { titleSeq = sq }
data Creator = Creator
{ creatorRole :: Maybe String
, creatorFileAs :: Maybe String
, creatorSeq :: Maybe Int
, creatorText :: String
}
deriving (Eq, Show)
refineCreator :: [Refinement] -> (String, Creator) -> Creator
refineCreator refinements (elid, creator) =
assignSeq . assignFileAs . assignRole $ creator
where
assignRole creator' =
let existingRole = creatorRole creator'
metaRole = maybe Nothing (Just . refText) $
findByIdProp elid "role" refinements
in creator' { creatorRole = existingRole `mplus` metaRole }
assignFileAs creator' =
let existingFileAs = creatorFileAs creator'
metaFileAs = maybe Nothing (Just . refText) $
findByIdProp elid "file-as" refinements
in creator' { creatorFileAs = existingFileAs `mplus` metaFileAs }
assignSeq creator' =
let sq = maybe Nothing (Just . read . refText) $
findByIdProp elid "display-seq" refinements
in creator' { creatorSeq = sq }
data Date = Date (Maybe String) String
deriving (Eq, Show)
getModified :: [Refinement] -> Maybe String
getModified refinements =
refText `fmap` findByIdProp "" "dcterms:modified" refinements
data Description = Description (Maybe String) String
deriving (Eq, Show)
data Metadata = Metadata
{ metaIds :: [Identifier]
, metaTitles :: [Title]
, metaLangs :: [String]
, metaContributors :: [Creator]
, metaCreators :: [Creator]
, metaDates :: [Date]
, metaModified :: Maybe String
, metaSource :: Maybe String
, metaType :: Maybe String
, metaCoverages :: [String]
, metaDescriptions :: [Description]
, metaFormats :: [String]
, metaPublishers :: [String]
, metaRelations :: [String]
, metaRights :: [String]
, metaSubjects :: [String]
}
deriving (Eq, Show)
emptyMetadata :: Metadata
emptyMetadata = Metadata
{ metaIds = []
, metaTitles = []
, metaLangs = []
, metaContributors = []
, metaCreators = []
, metaDates = []
, metaModified = Nothing
, metaSource = Nothing
, metaType = Nothing
, metaCoverages = []
, metaDescriptions = []
, metaFormats = []
, metaPublishers = []
, metaRelations = []
, metaRights = []
, metaSubjects = []
}