@@ -30,11 +30,12 @@ Conversion of 'Pandoc' documents to EPUB.
30module Text.Pandoc.Writers.EPUB ( writeEPUB2, writeEPUB3 ) where
30module Text.Pandoc.Writers.EPUB ( writeEPUB2, writeEPUB3 ) where
31import Data.IORef
31import Data.IORef
32import Data.Maybe ( fromMaybe, isNothing )
32import Data.Maybe ( fromMaybe, isNothing )
33−import Data.List ( isPrefixOf, intercalate )
33+import Data.List ( isPrefixOf, isInfixOf, intercalate )
34import System.Environment ( getEnv )
34import System.Environment ( getEnv )
35import Text.Printf (printf)
35import Text.Printf (printf)
36import System.FilePath ( (</>), (<.>), takeBaseName, takeExtension, takeFileName )
36import System.FilePath ( (</>), (<.>), takeBaseName, takeExtension, takeFileName )
37import qualified Data.ByteString.Lazy as B
37import qualified Data.ByteString.Lazy as B
38+import qualified Data.ByteString.Lazy.Char8 as B8
38import Text.Pandoc.UTF8 ( fromStringLazy )
39import Text.Pandoc.UTF8 ( fromStringLazy )
39import Codec.Archive.Zip
40import Codec.Archive.Zip
40import Data.Time.Clock.POSIX
41import Data.Time.Clock.POSIX
@@ -77,18 +78,22 @@ writeEPUB version opts doc@(Pandoc meta _) = do
77 let mkEntry path content = toEntry path epochtime content
78 let mkEntry path content = toEntry path epochtime content
78 let opts' = opts{ writerEmailObfuscation = NoObfuscation
79 let opts' = opts{ writerEmailObfuscation = NoObfuscation
79 , writerStandalone = True
80 , writerStandalone = True
81+ , writerHTMLMathMethod =
84+ else writerHTMLMathMethod opts
80 , writerWrapText = False }
85 , writerWrapText = False }
81 let sourceDir = writerSourceDirectory opts'
86 let sourceDir = writerSourceDirectory opts'
82 let vars = ("epub3", if epub3 then "true" else "false"):writerVariables opts'
87 let vars = ("epub3", if epub3 then "true" else "false"):writerVariables opts'
83 let mbCoverImage = lookup "epub-cover-image" vars
88 let mbCoverImage = lookup "epub-cover-image" vars
85− titlePageTemplate <- readDataFile (writerUserDataDir opts)
90+ titlePageTemplate <- readDataFile (writerUserDataDir opts')
86 $ "templates" </> "epub-titlepage" <.> "html"
91 $ "templates" </> "epub-titlepage" <.> "html"
88− coverImageTemplate <- readDataFile (writerUserDataDir opts)
93+ coverImageTemplate <- readDataFile (writerUserDataDir opts')
89 $ "templates" </> "epub-coverimage" <.> "html"
94 $ "templates" </> "epub-coverimage" <.> "html"
91− pageTemplate <- readDataFile (writerUserDataDir opts)
96+ pageTemplate <- readDataFile (writerUserDataDir opts')
92 $ "templates" </> "epub-page" <.> "html"
97 $ "templates" </> "epub-page" <.> "html"
94 -- cover page
99 -- cover page
@@ -117,7 +122,7 @@ writeEPUB version opts doc@(Pandoc meta _) = do
117 -- handle pictures
122 -- handle pictures
118 picsRef <- newIORef []
123 picsRef <- newIORef []
119 Pandoc _ blocks <- bottomUpM
124 Pandoc _ blocks <- bottomUpM
120− (transformInlines (writerHTMLMathMethod opts) sourceDir picsRef) doc
125+ (transformInlines (writerHTMLMathMethod opts') sourceDir picsRef) doc
121 pics <- readIORef picsRef
126 pics <- readIORef picsRef
122 let readPicEntry (oldsrc, newsrc) = readEntry [] oldsrc >>= \e ->
127 let readPicEntry (oldsrc, newsrc) = readEntry [] oldsrc >>= \e ->
123 return e{ eRelativePath = newsrc }
128 return e{ eRelativePath = newsrc }
@@ -125,7 +130,7 @@ writeEPUB version opts doc@(Pandoc meta _) = do
126 -- handle fonts
131 -- handle fonts
127 let mkFontEntry f = mkEntry (takeFileName f) `fmap` B.readFile f
132 let mkFontEntry f = mkEntry (takeFileName f) `fmap` B.readFile f
128− fontEntries <- mapM mkFontEntry $ writerEpubFonts opts
133+ fontEntries <- mapM mkFontEntry $ writerEpubFonts opts'
130 -- body pages
135 -- body pages
131 -- add level 1 header to beginning if none there
136 -- add level 1 header to beginning if none there
@@ -150,6 +155,9 @@ writeEPUB version opts doc@(Pandoc meta _) = do
151 let chapterEntries = zipWith chapToEntry [1..] chunks
156 let chapterEntries = zipWith chapToEntry [1..] chunks
158+ -- incredibly inefficient (TODO):
159+ let containsMathML ent = "<math" `isInfixOf` (B8.unpack $ fromEntry ent)
153 -- contents.opf
161 -- contents.opf
154 localeLang <- catch (liftM (map (\c -> if c == '_' then '-' else c) .
162 localeLang <- catch (liftM (map (\c -> if c == '_' then '-' else c) .
155 takeWhile (/='.')) $ getEnv "LANG")
163 takeWhile (/='.')) $ getEnv "LANG")
@@ -159,9 +167,11 @@ writeEPUB version opts doc@(Pandoc meta _) = do
159 Nothing -> localeLang
167 Nothing -> localeLang
160 uuid <- getRandomUUID
168 uuid <- getRandomUUID
161 let chapterNode ent = unode "item" !
169 let chapterNode ent = unode "item" !
162− [("id", takeBaseName $ eRelativePath ent),
170+ ([("id", takeBaseName $ eRelativePath ent),
163− ("href", eRelativePath ent),
171+ ("href", eRelativePath ent),
164− ("media-type", "application/xhtml+xml")] $ ()
172+ ("media-type", "application/xhtml+xml")]
173+ ++ [("properties","mathml switch") | epub3 &&
174+ containsMathML ent]) $ ()
165 let chapterRefNode ent = unode "itemref" !
175 let chapterRefNode ent = unode "itemref" !
166 [("idref", takeBaseName $ eRelativePath ent)] $ ()
176 [("idref", takeBaseName $ eRelativePath ent)] $ ()
167 let pictureNode ent = unode "item" !
177 let pictureNode ent = unode "item" !
@@ -360,8 +370,8 @@ transformInlines :: HTMLMathMethod
360 -> IORef [(FilePath, FilePath)] -- ^ (oldpath, newpath) images
370 -> IORef [(FilePath, FilePath)] -- ^ (oldpath, newpath) images
361 -> [Inline]
371 -> [Inline]
362 -> IO [Inline]
372 -> IO [Inline]
363−transformInlines _ _ _ (Image lab (src,_) : xs) | isNothing (imageTypeOf src) =
373+transformInlines _ _ _ (Image lab (src,_) : xs)
364− return $ Emph lab : xs
374+ | isNothing (imageTypeOf src) = return $ Emph lab : xs
365transformInlines _ sourceDir picsRef (Image lab (src,tit) : xs) = do
375transformInlines _ sourceDir picsRef (Image lab (src,tit) : xs) = do
366 let src' = unEscapeString src
376 let src' = unEscapeString src
367 pics <- readIORef picsRef
377 pics <- readIORef picsRef
@@ -379,11 +389,11 @@ transformInlines (MathML _) _ _ (x@(Math _ _) : xs) = do
379 writeHtmlString opts $ Pandoc (Meta [] [] []) [Plain [z]]
389 writeHtmlString opts $ Pandoc (Meta [] [] []) [Plain [z]]
380 mathml = writeHtmlInline def{writerHTMLMathMethod = MathML Nothing } x
390 mathml = writeHtmlInline def{writerHTMLMathMethod = MathML Nothing } x
381 fallback = writeHtmlInline def{writerHTMLMathMethod = PlainMath } x
391 fallback = writeHtmlInline def{writerHTMLMathMethod = PlainMath } x
382− inOps = "<ops:switch xmlns:ops=\"http://www.idpf.org/2007/ops\">" ++
392+ inSwitch = "<epub:switch><epub:case required-namespace=" ++
383− "<ops:case required-namespace=\"http://www.w3.org/1998/Math/MathML\">" ++
393+ "\"http://www.w3.org/1998/Math/MathML\">" ++ mathml ++
384− mathml ++ "</ops:case><ops:default>" ++ fallback ++ "</ops:default>" ++
394+ "</epub:case><epub:default>" ++ fallback ++
385− "</ops:switch>"
395+ "</epub:default></epub:switch>"
386− result = if "<math" `isPrefixOf` mathml then inOps else mathml
396+ result = if "<math" `isPrefixOf` mathml then inSwitch else mathml
387 return $ RawInline "html" result : xs
397 return $ RawInline "html" result : xs
388transformInlines _ _ _ xs = return xs
398transformInlines _ _ _ xs = return xs