git.iko.soy/typeable/pandoc
on master help sign in
EPUB writer: Handle multiple dates with OPF `event` attributes.
3c77ab9John MacFarlane
src/Text/Pandoc/Writers/EPUB.hs+38−9
@@ -72,7 +72,7 @@ data Chapter = Chapter (Maybe [Int]) [Block]
72data EPUBMetadata = EPUBMetadata{
72data EPUBMetadata = EPUBMetadata{
73 epubIdentifier :: [Identifier]
73 epubIdentifier :: [Identifier]
74 , epubTitle :: [Title]
74 , epubTitle :: [Title]
75− , epubDate :: String
75+ , epubDate :: [Date]
76 , epubLanguage :: String
76 , epubLanguage :: String
77 , epubCreator :: [Creator]
77 , epubCreator :: [Creator]
78 , epubContributor :: [Creator]
78 , epubContributor :: [Creator]
@@ -93,6 +93,11 @@ data Stylesheet = StylesheetPath FilePath
93 | StylesheetContents String
93 | StylesheetContents String
94 deriving Show
94 deriving Show
95
95
96+data Date = Date{
97+ dateText :: String
98+ , dateEvent :: Maybe String
99+ } deriving Show
100+
96data Creator = Creator{
101data Creator = Creator{
97 creatorText :: String
102 creatorText :: String
98 , creatorRole :: Maybe String
103 , creatorRole :: Maybe String
@@ -159,7 +164,9 @@ getEPUBMetadata opts meta = do
159 if null (epubDate m)
164 if null (epubDate m)
160 then do
165 then do
161 currentTime <- getCurrentTime
166 currentTime <- getCurrentTime
167+ return $ m{ epubDate = [ Date{
162− return $ m{ epubDate = showDateTimeISO8601 currentTime }
168+ dateText = showDateTimeISO8601 currentTime
169+ , dateEvent = Nothing } ] }
163 else return m
170 else return m
164 let addAuthor m =
171 let addAuthor m =
165 if any (\c -> creatorRole c == Just "aut") $ epubCreator m
172 if any (\c -> creatorRole c == Just "aut") $ epubCreator m
@@ -183,8 +190,10 @@ addMetadataFromXML e@(Element (QName name _ (Just "dc")) attrs _ _) md
183 , titleFileAs = getAttr "file-as"
190 , titleFileAs = getAttr "file-as"
184 , titleType = getAttr "type"
191 , titleType = getAttr "type"
185 } : epubTitle md }
192 } : epubTitle md }
186− | name == "date" = md{ epubDate = fromMaybe "" $ normalizeDate'
193+ | name == "date" = md{ epubDate =
187− $ strContent e }
194+ Date{ dateText = fromMaybe "" $ normalizeDate' $ strContent e
195+ , dateEvent = getAttr "event"
196+ } : epubDate md }
188 | name == "language" = md{ epubLanguage = strContent e }
197 | name == "language" = md{ epubLanguage = strContent e }
189 | name == "creator" = md{ epubCreator =
198 | name == "creator" = md{ epubCreator =
190 Creator{ creatorText = strContent e
199 Creator{ creatorText = strContent e
@@ -249,6 +258,16 @@ getCreator s meta = getList s meta handleMetaValue
249 , creatorRole = metaValueToString <$> M.lookup "role" m }
258 , creatorRole = metaValueToString <$> M.lookup "role" m }
250 handleMetaValue mv = Creator (metaValueToString mv) Nothing Nothing
259 handleMetaValue mv = Creator (metaValueToString mv) Nothing Nothing
251
260
261+getDate :: String -> Meta -> [Date]
262+getDate s meta = getList s meta handleMetaValue
263+ where handleMetaValue (MetaMap m) =
264+ Date{ dateText = maybe "" id $
265+ M.lookup "text" m >>= normalizeDate' . metaValueToString
266+ , dateEvent = metaValueToString <$> M.lookup "event" m }
267+ handleMetaValue mv = Date { dateText = maybe ""
268+ id $ normalizeDate' $ metaValueToString mv
269+ , dateEvent = Nothing }
270+
252simpleList :: String -> Meta -> [String]
271simpleList :: String -> Meta -> [String]
253simpleList s meta =
272simpleList s meta =
254 case lookupMeta s meta of
273 case lookupMeta s meta of
@@ -278,8 +297,7 @@ metadataFromMeta opts meta = EPUBMetadata{
278 }
297 }
279 where identifiers = getIdentifier meta
298 where identifiers = getIdentifier meta
280 titles = getTitle meta
299 titles = getTitle meta
281− date = fromMaybe "" $
300+ date = getDate "date" meta
282− (metaValueToString <$> lookupMeta "date" meta) >>= normalizeDate'
283 language = maybe "" metaValueToString $
301 language = maybe "" metaValueToString $
284 lookupMeta "language" meta `mplus` lookupMeta "lang" meta
302 lookupMeta "language" meta `mplus` lookupMeta "lang" meta
285 creators = getCreator "creator" meta
303 creators = getCreator "creator" meta
@@ -637,7 +655,14 @@ metadataElement version md currentTime =
637 identifierNodes = withIds "epub-id" toIdentifierNode $
655 identifierNodes = withIds "epub-id" toIdentifierNode $
638 epubIdentifier md
656 epubIdentifier md
639 titleNodes = withIds "epub-title" toTitleNode $ epubTitle md
657 titleNodes = withIds "epub-title" toTitleNode $ epubTitle md
658+ dateNodes = if version == EPUB2
640− dateNodes = dcTag' "date" $ epubDate md
659+ then withIds "epub-date" toDateNode $ epubDate md
660+ else -- epub3 allows only one dc:date
661+ -- http://www.idpf.org/epub/30/spec/epub30-publications.html#sec-opf-dcdate
662+ case epubDate md of
663+ [] -> []
664+ (x:_) -> [dcNode "date" ! [("id","epub-date")]
665+ $ dateText x]
641 languageNodes = [dcTag "language" $ epubLanguage md]
666 languageNodes = [dcTag "language" $ epubLanguage md]
642 creatorNodes = withIds "epub-creator" (toCreatorNode "creator") $
667 creatorNodes = withIds "epub-creator" (toCreatorNode "creator") $
643 epubCreator md
668 epubCreator md
@@ -671,7 +696,7 @@ metadataElement version md currentTime =
671 (schemeToOnix `fmap` scheme)
696 (schemeToOnix `fmap` scheme)
672 toCreatorNode s id' creator
697 toCreatorNode s id' creator
673 | version == EPUB2 = [dcNode s !
698 | version == EPUB2 = [dcNode s !
674− ([("id",id')] ++
699+ (("id",id') :
675 maybe [] (\x -> [("opf:file-as",x)]) (creatorFileAs creator) ++
700 maybe [] (\x -> [("opf:file-as",x)]) (creatorFileAs creator) ++
676 maybe [] (\x -> [("opf:role",x)])
701 maybe [] (\x -> [("opf:role",x)])
677 (creatorRole creator >>= toRelator)) $ creatorText creator]
702 (creatorRole creator >>= toRelator)) $ creatorText creator]
@@ -685,7 +710,7 @@ metadataElement version md currentTime =
685 (creatorRole creator >>= toRelator)
710 (creatorRole creator >>= toRelator)
686 toTitleNode id' title
711 toTitleNode id' title
687 | version == EPUB2 = [dcNode "title" !
712 | version == EPUB2 = [dcNode "title" !
688− ([("id",id')] ++
713+ (("id",id') :
689 maybe [] (\x -> [("opf:file-as",x)]) (titleFileAs title) ++
714 maybe [] (\x -> [("opf:file-as",x)]) (titleFileAs title) ++
690 maybe [] (\x -> [("opf:title-type",x)]) (titleType title)) $
715 maybe [] (\x -> [("opf:title-type",x)]) (titleType title)) $
691 titleText title]
716 titleText title]
@@ -697,6 +722,10 @@ metadataElement version md currentTime =
697 maybe [] (\x -> [unode "meta" !
722 maybe [] (\x -> [unode "meta" !
698 [("refines",'#':id'),("property","title-type")] $ x])
723 [("refines",'#':id'),("property","title-type")] $ x])
699 (titleType title)
724 (titleType title)
725+ toDateNode id' date = [dcNode "date" !
726+ (("id",id') :
727+ maybe [] (\x -> [("opf:event",x)]) (dateEvent date)) $
728+ dateText date]
700 schemeToOnix "ISBN-10" = "02"
729 schemeToOnix "ISBN-10" = "02"
701 schemeToOnix "GTIN-13" = "03"
730 schemeToOnix "GTIN-13" = "03"
702 schemeToOnix "UPC" = "04"
731 schemeToOnix "UPC" = "04"