@@ -21,7 +21,7 @@ import Prelude
21import Codec.Archive.Zip (Archive (..), Entry, findEntryByPath, fromEntry,
21import Codec.Archive.Zip (Archive (..), Entry, findEntryByPath, fromEntry,
22 toArchiveOrFail)
22 toArchiveOrFail)
23import Control.DeepSeq (NFData, deepseq)
23import Control.DeepSeq (NFData, deepseq)
24−import Control.Monad (guard, liftM)
24+import Control.Monad (guard, liftM, liftM2, mplus)
25import Control.Monad.Except (throwError)
25import Control.Monad.Except (throwError)
26import qualified Data.ByteString.Lazy as BL (ByteString)
26import qualified Data.ByteString.Lazy as BL (ByteString)
27import Data.List (isInfixOf, isPrefixOf)
27import Data.List (isInfixOf, isPrefixOf)
@@ -62,8 +62,8 @@ archiveToEPUB :: (PandocMonad m) => ReaderOptions -> Archive -> m Pandoc
62archiveToEPUB os archive = do
62archiveToEPUB os archive = do
63 -- root is path to folder with manifest file in
63 -- root is path to folder with manifest file in
64 (root, content) <- getManifest archive
64 (root, content) <- getManifest archive
65− meta <- parseMeta content
65+ (coverId, meta) <- parseMeta content
66− (cover, items) <- parseManifest content
66+ (cover, items) <- parseManifest content coverId
67 -- No need to collapse here as the image path is from the manifest file
67 -- No need to collapse here as the image path is from the manifest file
68 let coverDoc = fromMaybe mempty (imageToPandoc <$> cover)
68 let coverDoc = fromMaybe mempty (imageToPandoc <$> cover)
69 spine <- parseSpine items content
69 spine <- parseSpine items content
@@ -124,18 +124,22 @@ imageToPandoc s = B.doc . B.para $ B.image s "" mempty
124imageMimes :: [MimeType]
124imageMimes :: [MimeType]
125imageMimes = ["image/gif", "image/jpeg", "image/png"]
125imageMimes = ["image/gif", "image/jpeg", "image/png"]
127+type CoverId = String
127type CoverImage = FilePath
129type CoverImage = FilePath
129−parseManifest :: (PandocMonad m) => Element -> m (Maybe CoverImage, Items)
131+parseManifest :: (PandocMonad m) => Element -> Maybe CoverId -> m (Maybe CoverImage, Items)
130−parseManifest content = do
132+parseManifest content coverId = do
131 manifest <- findElementE (dfName "manifest") content
133 manifest <- findElementE (dfName "manifest") content
132 let items = findChildren (dfName "item") manifest
134 let items = findChildren (dfName "item") manifest
133 r <- mapM parseItem items
135 r <- mapM parseItem items
134 let cover = findAttr (emptyName "href") =<< filterChild findCover manifest
136 let cover = findAttr (emptyName "href") =<< filterChild findCover manifest
135− return (cover, M.fromList r)
137+ return (cover `mplus` coverId, M.fromList r)
137 findCover e = maybe False (isInfixOf "cover-image")
139 findCover e = maybe False (isInfixOf "cover-image")
138 (findAttr (emptyName "properties") e)
140 (findAttr (emptyName "properties") e)
142+ (liftM2 (==) coverId (findAttr (emptyName "id") e))
139 parseItem e = do
143 parseItem e = do
140 uid <- findAttrE (emptyName "id") e
144 uid <- findAttrE (emptyName "id") e
141 href <- findAttrE (emptyName "href") e
145 href <- findAttrE (emptyName "href") e
@@ -153,14 +157,17 @@ parseSpine is e = do
153 guard linear
157 guard linear
154 findAttr (emptyName "idref") ref
158 findAttr (emptyName "idref") ref
156−parseMeta :: PandocMonad m => Element -> m Meta
160+parseMeta :: PandocMonad m => Element -> m (Maybe CoverId, Meta)
157parseMeta content = do
161parseMeta content = do
158 meta <- findElementE (dfName "metadata") content
162 meta <- findElementE (dfName "metadata") content
159 let dcspace (QName _ (Just "http://purl.org/dc/elements/1.1/") (Just "dc")) = True
163 let dcspace (QName _ (Just "http://purl.org/dc/elements/1.1/") (Just "dc")) = True
160 dcspace _ = False
164 dcspace _ = False
161 let dcs = filterChildrenName dcspace meta
165 let dcs = filterChildrenName dcspace meta
162 let r = foldr parseMetaItem nullMeta dcs
166 let r = foldr parseMetaItem nullMeta dcs
167+ let coverId = findAttr (emptyName "content") =<< filterChild findCover meta
163− return r
168+ return (coverId, r)
170+ findCover e = maybe False (== "cover") (findAttr (emptyName "name") e)
165-- http://www.idpf.org/epub/30/spec/epub30-publications.html#sec-metadata-elem
172-- http://www.idpf.org/epub/30/spec/epub30-publications.html#sec-metadata-elem
166parseMetaItem :: Element -> Meta -> Meta
173parseMetaItem :: Element -> Meta -> Meta