From 743d1b368f8c8bbd393454915f71a02453659423 Mon Sep 17 00:00:00 2001 From: John MacFarlane <jgm@berkeley.edu> Date: Sat, 24 Nov 2018 20:34:54 -0800 Subject: [PATCH] EPUB writer: handle calibre metadata. Nodes of the form <meta name="calibre:series" content="Classics on War and Politics"/> are now included from an epub XML metadata file. You can also include this information in your YAML metadata, like so: calibre: series: Classics on War and Policitics In addition, ibooks-specific metadata can now be included via an XML file. (Previously, it could only be included via YAML metadata, see #2693.) Closes #5098. --- src/Text/Pandoc/Writers/EPUB.hs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs index a4b841efd..93c685ffa 100644 --- a/src/Text/Pandoc/Writers/EPUB.hs +++ b/src/Text/Pandoc/Writers/EPUB.hs @@ -110,6 +110,7 @@ data EPUBMetadata = EPUBMetadata{ , epubStylesheets :: [FilePath] , epubPageDirection :: Maybe ProgressionDirection , epubIbooksFields :: [(String, String)] + , epubCalibreFields :: [(String, String)] } deriving Show data Date = Date{ @@ -250,6 +251,18 @@ addMetadataFromXML e@(Element (QName name _ (Just "dc")) attrs _ _) md | name == "rights" = md { epubRights = Just $ strContent e } | otherwise = md where getAttr n = lookupAttr (opfName n) attrs +addMetadataFromXML e@(Element (QName "meta" _ _) attrs _ _) md = + case getAttr "property" of + Just s | "ibooks:" `isPrefixOf` s -> + md{ epubIbooksFields = (drop 7 s, strContent e) : + epubIbooksFields md } + _ -> case getAttr "name" of + Just s | "calibre:" `isPrefixOf` s -> + md{ epubCalibreFields = + (drop 8 s, fromMaybe "" $ getAttr "content") : + epubCalibreFields md } + _ -> md + where getAttr n = lookupAttr (unqual n) attrs addMetadataFromXML _ md = md metaValueToString :: MetaValue -> String @@ -333,6 +346,7 @@ metadataFromMeta opts meta = EPUBMetadata{ , epubStylesheets = stylesheets , epubPageDirection = pageDirection , epubIbooksFields = ibooksFields + , epubCalibreFields = calibreFields } where identifiers = getIdentifier meta titles = getTitle meta @@ -364,6 +378,10 @@ metadataFromMeta opts meta = EPUBMetadata{ Just (MetaMap mp) -> M.toList $ M.map metaValueToString mp _ -> [] + calibreFields = case lookupMeta "calibre" meta of + Just (MetaMap mp) + -> M.toList $ M.map metaValueToString mp + _ -> [] -- | Produce an EPUB2 file from a Pandoc document. writeEPUB2 :: PandocMonad m @@ -856,7 +874,7 @@ metadataElement version md currentTime = unode "metadata" ! [("xmlns:dc","http://purl.org/dc/elements/1.1/") ,("xmlns:opf","http://www.idpf.org/2007/opf")] $ mdNodes where mdNodes = identifierNodes ++ titleNodes ++ dateNodes - ++ languageNodes ++ ibooksNodes + ++ languageNodes ++ ibooksNodes ++ calibreNodes ++ creatorNodes ++ contributorNodes ++ subjectNodes ++ descriptionNodes ++ typeNodes ++ formatNodes ++ publisherNodes ++ sourceNodes ++ relationNodes @@ -877,6 +895,9 @@ metadataElement version md currentTime = $ dateText x] ibooksNodes = map ibooksNode (epubIbooksFields md) ibooksNode (k, v) = unode "meta" ! [("property", "ibooks:" ++ k)] $ v + calibreNodes = map calibreNode (epubCalibreFields md) + calibreNode (k, v) = unode "meta" ! [("name", "calibre:" ++ k), + ("content", v)] $ () languageNodes = [dcTag "language" $ epubLanguage md] creatorNodes = withIds "epub-creator" (toCreatorNode "creator") $ epubCreator md