git.iko.soy/typeable/pandoc
on master help sign in
Improved support for MathML in EPUB3.

* MathML math method now used always in EPUB3 (even if another math method specified in options). * epub:switch is used to specify a non-MathML default. This is supposed to proide a good fallback behavior in older readers, though I'm not sure how well it works in practice.

commit569954e1d5992bc24642347d60e1e5619623d4bc authorJohn MacFarlane <fiddlosopher@gmail.com> dateSun 4 Nov 2012, 10:37 (14 years ago) parentdfca599
2 files changed+27−17
src/Text/Pandoc/Writers/EPUB.hs+26−16 templates+1−1
src/Text/Pandoc/Writers/EPUB.hs+26−16
@@ -30,11 +30,12 @@ Conversion of 'Pandoc' documents to EPUB.
3030module Text.Pandoc.Writers.EPUB ( writeEPUB2, writeEPUB3 ) where
3131import Data.IORef
3232import Data.Maybe ( fromMaybe, isNothing )
33−import Data.List ( isPrefixOf, intercalate )
33+import Data.List ( isPrefixOf, isInfixOf, intercalate )
3434import System.Environment ( getEnv )
3535import Text.Printf (printf)
3636import System.FilePath ( (</>), (<.>), takeBaseName, takeExtension, takeFileName )
3737import qualified Data.ByteString.Lazy as B
38+import qualified Data.ByteString.Lazy.Char8 as B8
3839import Text.Pandoc.UTF8 ( fromStringLazy )
3940import Codec.Archive.Zip
4041import Data.Time.Clock.POSIX
@@ -77,18 +78,22 @@ writeEPUB version opts doc@(Pandoc meta _) = do
7778 let mkEntry path content = toEntry path epochtime content
7879 let opts' = opts{ writerEmailObfuscation = NoObfuscation
7980 , writerStandalone = True
81+ , writerHTMLMathMethod =
82+ if epub3
83+ then MathML Nothing
84+ else writerHTMLMathMethod opts
8085 , writerWrapText = False }
8186 let sourceDir = writerSourceDirectory opts'
8287 let vars = ("epub3", if epub3 then "true" else "false"):writerVariables opts'
8388 let mbCoverImage = lookup "epub-cover-image" vars
8489
85− titlePageTemplate <- readDataFile (writerUserDataDir opts)
90+ titlePageTemplate <- readDataFile (writerUserDataDir opts')
8691 $ "templates" </> "epub-titlepage" <.> "html"
8792
88− coverImageTemplate <- readDataFile (writerUserDataDir opts)
93+ coverImageTemplate <- readDataFile (writerUserDataDir opts')
8994 $ "templates" </> "epub-coverimage" <.> "html"
9095
91− pageTemplate <- readDataFile (writerUserDataDir opts)
96+ pageTemplate <- readDataFile (writerUserDataDir opts')
9297 $ "templates" </> "epub-page" <.> "html"
9398
9499 -- cover page
@@ -117,7 +122,7 @@ writeEPUB version opts doc@(Pandoc meta _) = do
117122 -- handle pictures
118123 picsRef <- newIORef []
119124 Pandoc _ blocks <- bottomUpM
120− (transformInlines (writerHTMLMathMethod opts) sourceDir picsRef) doc
125+ (transformInlines (writerHTMLMathMethod opts') sourceDir picsRef) doc
121126 pics <- readIORef picsRef
122127 let readPicEntry (oldsrc, newsrc) = readEntry [] oldsrc >>= \e ->
123128 return e{ eRelativePath = newsrc }
@@ -125,7 +130,7 @@ writeEPUB version opts doc@(Pandoc meta _) = do
125130
126131 -- handle fonts
127132 let mkFontEntry f = mkEntry (takeFileName f) `fmap` B.readFile f
128− fontEntries <- mapM mkFontEntry $ writerEpubFonts opts
133+ fontEntries <- mapM mkFontEntry $ writerEpubFonts opts'
129134
130135 -- body pages
131136 -- add level 1 header to beginning if none there
@@ -150,6 +155,9 @@ writeEPUB version opts doc@(Pandoc meta _) = do
150155
151156 let chapterEntries = zipWith chapToEntry [1..] chunks
152157
158+ -- incredibly inefficient (TODO):
159+ let containsMathML ent = "<math" `isInfixOf` (B8.unpack $ fromEntry ent)
160+
153161 -- contents.opf
154162 localeLang <- catch (liftM (map (\c -> if c == '_' then '-' else c) .
155163 takeWhile (/='.')) $ getEnv "LANG")
@@ -159,9 +167,11 @@ writeEPUB version opts doc@(Pandoc meta _) = do
159167 Nothing -> localeLang
160168 uuid <- getRandomUUID
161169 let chapterNode ent = unode "item" !
162− [("id", takeBaseName $ eRelativePath ent),
163− ("href", eRelativePath ent),
164− ("media-type", "application/xhtml+xml")] $ ()
170+ ([("id", takeBaseName $ eRelativePath ent),
171+ ("href", eRelativePath ent),
172+ ("media-type", "application/xhtml+xml")]
173+ ++ [("properties","mathml switch") | epub3 &&
174+ containsMathML ent]) $ ()
165175 let chapterRefNode ent = unode "itemref" !
166176 [("idref", takeBaseName $ eRelativePath ent)] $ ()
167177 let pictureNode ent = unode "item" !
@@ -360,8 +370,8 @@ transformInlines :: HTMLMathMethod
360370 -> IORef [(FilePath, FilePath)] -- ^ (oldpath, newpath) images
361371 -> [Inline]
362372 -> IO [Inline]
363−transformInlines _ _ _ (Image lab (src,_) : xs) | isNothing (imageTypeOf src) =
364− return $ Emph lab : xs
373+transformInlines _ _ _ (Image lab (src,_) : xs)
374+ | isNothing (imageTypeOf src) = return $ Emph lab : xs
365375transformInlines _ sourceDir picsRef (Image lab (src,tit) : xs) = do
366376 let src' = unEscapeString src
367377 pics <- readIORef picsRef
@@ -379,11 +389,11 @@ transformInlines (MathML _) _ _ (x@(Math _ _) : xs) = do
379389 writeHtmlString opts $ Pandoc (Meta [] [] []) [Plain [z]]
380390 mathml = writeHtmlInline def{writerHTMLMathMethod = MathML Nothing } x
381391 fallback = writeHtmlInline def{writerHTMLMathMethod = PlainMath } x
382− inOps = "<ops:switch xmlns:ops=\"http://www.idpf.org/2007/ops\">" ++
383− "<ops:case required-namespace=\"http://www.w3.org/1998/Math/MathML\">" ++
384− mathml ++ "</ops:case><ops:default>" ++ fallback ++ "</ops:default>" ++
385− "</ops:switch>"
386− result = if "<math" `isPrefixOf` mathml then inOps else mathml
392+ inSwitch = "<epub:switch><epub:case required-namespace=" ++
393+ "\"http://www.w3.org/1998/Math/MathML\">" ++ mathml ++
394+ "</epub:case><epub:default>" ++ fallback ++
395+ "</epub:default></epub:switch>"
396+ result = if "<math" `isPrefixOf` mathml then inSwitch else mathml
387397 return $ RawInline "html" result : xs
388398transformInlines _ _ _ xs = return xs
389399
templates+1−1

Submodule changed.