From 0640c4c9859aa5a3ede082c190fcd5883c24ac83 Mon Sep 17 00:00:00 2001 From: nibras shami <74427567+vreoo@users.noreply.github.com> Date: Sun, 17 May 2026 12:02:34 +0300 Subject: [PATCH] EPUB writer: support multiple EPUB versions for raw content (#11628). This change ensures that raw content marked `epub2` will appear in (only) EPUBv2 output and content marked `epub3` will appear in (only) EPUBv3 output. --- src/Text/Pandoc/Writers/EPUB.hs | 39 +++++++++++++++++------------- src/Text/Pandoc/Writers/HTML.hs | 10 ++++++++ test/command/8880.md | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 test/command/8880.md diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs index 030270571..39d3f6274 100644 --- a/src/Text/Pandoc/Writers/EPUB.hs +++ b/src/Text/Pandoc/Writers/EPUB.hs @@ -466,8 +466,8 @@ pandocToEPUB :: PandocMonad m pandocToEPUB version opts doc = do let doc' = ensureValidXmlIdentifiers doc -- handle pictures - Pandoc meta blocks <- walkM (transformInline opts) doc' >>= - walkM transformBlock + Pandoc meta blocks <- walkM (transformInline version opts) doc' >>= + walkM (transformBlock version) picEntries <- mapMaybe (snd . snd) <$> gets stMediaPaths epubSubdir <- gets stEpubSubdir @@ -1203,42 +1203,47 @@ getMediaNextNewName ext = do modify $ \st -> st { stMediaNextId = nextId + 1 } return $ "file" ++ show nextId ++ ext -isHtmlFormat :: Format -> Bool -isHtmlFormat (Format "html") = True -isHtmlFormat (Format "html4") = True -isHtmlFormat (Format "html5") = True -isHtmlFormat _ = False +isHtmlFormat :: EPUBVersion -> Format -> Bool +isHtmlFormat _ (Format "html") = True +isHtmlFormat _ (Format "html4") = True +isHtmlFormat _ (Format "html5") = True +isHtmlFormat _ (Format "epub") = True +isHtmlFormat EPUB2 (Format "epub2") = True +isHtmlFormat EPUB3 (Format "epub3") = True +isHtmlFormat _ _ = False transformBlock :: PandocMonad m - => Block + => EPUBVersion + -> Block -> E m Block -transformBlock (RawBlock fmt raw) - | isHtmlFormat fmt = do +transformBlock version (RawBlock fmt raw) + | isHtmlFormat version fmt = do let tags = parseTags raw tags' <- mapM transformTag tags return $ RawBlock fmt (renderTags' tags') -transformBlock b = return b +transformBlock _ b = return b transformInline :: PandocMonad m - => WriterOptions + => EPUBVersion + -> WriterOptions -> Inline -> E m Inline -transformInline _opts (Image attr@(_,_,kvs) lab (src,tit)) +transformInline _ _opts (Image attr@(_,_,kvs) lab (src,tit)) | isNothing (lookup "external" kvs) = do newsrc <- modifyMediaRef $ T.unpack src return $ Image attr lab ("../" <> newsrc, tit) -transformInline opts x@(Math t m) +transformInline _ opts x@(Math t m) | WebTeX url <- writerHTMLMathMethod opts = do newsrc <- modifyMediaRef (T.unpack (url <> urlEncode m)) let mathclass = if t == DisplayMath then "display" else "inline" return $ Span ("",["math",mathclass],[]) [Image nullAttr [x] ("../" <> newsrc, "")] -transformInline _opts (RawInline fmt raw) - | isHtmlFormat fmt = do +transformInline version _opts (RawInline fmt raw) + | isHtmlFormat version fmt = do let tags = parseTags raw tags' <- mapM transformTag tags return $ RawInline fmt (renderTags' tags') -transformInline _ x = return x +transformInline _ _ x = return x (!) :: (t -> Element) -> [(Text, Text)] -> t -> Element (!) f attrs n = add_attrs (map (\(k,v) -> Attr (unqual k) v) attrs) (f n) diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index 93473a327..0f1d378a9 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -1795,10 +1795,20 @@ intrinsicEventsHTML4 = isRawHtml :: PandocMonad m => Format -> StateT WriterState m Bool isRawHtml f = do html5 <- gets stHtml5 + epubVersion <- gets stEPUBVersion return $ f == Format "html" || ((html5 && f == Format "html5") || f == Format "html4") || + isEpubFormat epubVersion f || isSlideVariant f +-- | Check to see if Format matches with an EPUB variant +isEpubFormat :: Maybe EPUBVersion -> Format -> Bool +isEpubFormat Nothing _ = False +isEpubFormat (Just EPUB2) f = + f == Format "epub" || f == Format "epub2" +isEpubFormat (Just EPUB3) f = + f == Format "epub" || f == Format "epub3" + -- | Check to see if Format matches with an HTML slide variant isSlideVariant :: Format -> Bool isSlideVariant f = f `elem` [Format "s5", Format "slidy", Format "slideous", diff --git a/test/command/8880.md b/test/command/8880.md new file mode 100644 index 000000000..3aa9417b2 --- /dev/null +++ b/test/command/8880.md @@ -0,0 +1,42 @@ +Raw EPUB attributes are rendered in EPUB output. + +``` +% pandoc -f native -t epub --metadata title=Raw -o - | pandoc -f epub -t html +[ RawBlock (Format "epub") "
ok
" ] +^D ++
+
ok
+ok
+~~~ +^D ++
+
ok
+~~~ +^D ++
+
ok
+