git.iko.soy/typeable/pandoc
on master help sign in
Allow --self-contained to get content from MediaBag.

Added a parameter to makeSelfContained (API change).

commite4913d6dba1d413715fb68fd91683ab7b321bec8 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 30 Jul 2014, 15:26 (12 years ago) parent23d8066
3 files changed+38−27
pandoc.hs+3−1 src/Text/Pandoc/SelfContained.hs+34−25 src/Text/Pandoc/Writers/EPUB.hs+1−1
pandoc.hs+3−1
@@ -1281,7 +1281,9 @@ main = do
12811281 ["html","html+lhs","html5","html5+lhs",
12821282 "s5","slidy","slideous","dzslides","revealjs"]
12831283 selfcontain = if selfContained && htmlFormat
1284− then makeSelfContained datadir
1284+ then makeSelfContained
1285+ (writerMediaBag writerOptions')
1286+ (writerUserDataDir writerOptions')
12851287 else return
12861288 handleEntities = if htmlFormat && ascii
12871289 then toEntities
src/Text/Pandoc/SelfContained.hs+34−25
@@ -35,50 +35,53 @@ import Text.HTML.TagSoup
3535import Network.URI (isURI, escapeURIString)
3636import Data.ByteString.Base64
3737import qualified Data.ByteString.Char8 as B
38+import qualified Data.ByteString as BS
3839import Data.ByteString (ByteString)
3940import System.FilePath (takeExtension, dropExtension, takeDirectory, (</>))
4041import Data.Char (toLower, isAscii, isAlphaNum)
4142import Codec.Compression.GZip as Gzip
4243import qualified Data.ByteString.Lazy as L
43−import Text.Pandoc.Shared (renderTags', openURL, readDataFile, err)
44+import Text.Pandoc.Shared (renderTags', openURL, readDataFile, err, MediaBag)
4445import Text.Pandoc.UTF8 (toString, fromString)
4546import Text.Pandoc.MIME (getMimeType)
4647import System.Directory (doesFileExist)
48+import qualified Data.Map as M
4749
4850isOk :: Char -> Bool
4951isOk c = isAscii c && isAlphaNum c
5052
51−convertTag :: Maybe FilePath -> Tag String -> IO (Tag String)
52−convertTag userdata t@(TagOpen tagname as)
53+convertTag :: MediaBag -> Maybe FilePath -> Tag String -> IO (Tag String)
54+convertTag media userdata t@(TagOpen tagname as)
5355 | tagname `elem` ["img", "embed", "video", "input", "audio", "source"] = do
5456 as' <- mapM processAttribute as
5557 return $ TagOpen tagname as'
5658 where processAttribute (x,y) =
5759 if x == "src" || x == "href" || x == "poster"
5860 then do
59− (raw, mime) <- getRaw userdata (fromAttrib "type" t) y
61+ (raw, mime) <- getRaw media userdata (fromAttrib "type" t) y
6062 let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)
6163 return (x, enc)
6264 else return (x,y)
63−convertTag userdata t@(TagOpen "script" as) =
65+convertTag media userdata t@(TagOpen "script" as) =
6466 case fromAttrib "src" t of
6567 [] -> return t
6668 src -> do
67− (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
69+ (raw, mime) <- getRaw media userdata (fromAttrib "type" t) src
6870 let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
6971 return $ TagOpen "script" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
70−convertTag userdata t@(TagOpen "link" as) =
72+convertTag media userdata t@(TagOpen "link" as) =
7173 case fromAttrib "href" t of
7274 [] -> return t
7375 src -> do
74− (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
76+ (raw, mime) <- getRaw media userdata (fromAttrib "type" t) src
7577 let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
7678 return $ TagOpen "link" (("href",enc) : [(x,y) | (x,y) <- as, x /= "href"])
77−convertTag _ t = return t
79+convertTag _ _ t = return t
7880
7981-- NOTE: This is really crude, it doesn't respect CSS comments.
80−cssURLs :: Maybe FilePath -> FilePath -> ByteString -> IO ByteString
81−cssURLs userdata d orig =
82+cssURLs :: MediaBag -> Maybe FilePath -> FilePath -> ByteString
83+ -> IO ByteString
84+cssURLs media userdata d orig =
8285 case B.breakSubstring "url(" orig of
8386 (x,y) | B.null y -> return orig
8487 | otherwise -> do
@@ -91,14 +94,15 @@ cssURLs userdata d orig =
9194 let url' = if isURI url
9295 then url
9396 else d </> url
94− (raw, mime) <- getRaw userdata "" url'
95− rest <- cssURLs userdata d v
97+ (raw, mime) <- getRaw media userdata "" url'
98+ rest <- cssURLs media userdata d v
9699 let enc = "data:" `B.append` fromString mime `B.append`
97100 ";base64," `B.append` (encode raw)
98101 return $ x `B.append` "url(" `B.append` enc `B.append` rest
99102
100−getItem :: Maybe FilePath -> String -> IO (ByteString, Maybe String)
101−getItem userdata f =
103+getItem :: MediaBag -> Maybe FilePath -> String
104+ -> IO (ByteString, Maybe String)
105+getItem media userdata f =
102106 if isURI f
103107 then openURL f >>= either handleErr return
104108 else do
@@ -110,14 +114,19 @@ getItem userdata f =
110114 ".gz" -> getMimeType $ dropExtension f'
111115 x -> getMimeType x
112116 exists <- doesFileExist f'
113− cont <- if exists then B.readFile f' else readDataFile userdata f'
117+ cont <- if exists
118+ then B.readFile f'
119+ else case M.lookup f media of
120+ Just bs -> return $ BS.concat $ L.toChunks bs
121+ Nothing -> readDataFile userdata f'
114122 return (cont, mime)
115123 where handleErr e = err 61 $ "Failed to retrieve " ++ f ++ "\n" ++ show e
116124
117−getRaw :: Maybe FilePath -> String -> String -> IO (ByteString, String)
118−getRaw userdata mimetype src = do
125+getRaw :: MediaBag -> Maybe FilePath -> String -> String
126+ -> IO (ByteString, String)
127+getRaw media userdata mimetype src = do
119128 let ext = map toLower $ takeExtension src
120− (raw, respMime) <- getItem userdata src
129+ (raw, respMime) <- getItem media userdata src
121130 let raw' = if ext == ".gz"
122131 then B.concat $ L.toChunks $ Gzip.decompress $ L.fromChunks
123132 $ [raw]
@@ -128,20 +137,20 @@ getRaw userdata mimetype src = do
128137 (x, Nothing) -> x
129138 (_, Just x ) -> x
130139 result <- if mime == "text/css"
131− then cssURLs userdata (takeDirectory src) raw'
140+ then cssURLs media userdata (takeDirectory src) raw'
132141 else return raw'
133142 return (result, mime)
134143
135144-- | Convert HTML into self-contained HTML, incorporating images,
136145-- scripts, and CSS using data: URIs. Items specified using absolute
137146-- URLs will be downloaded; those specified using relative URLs will
138−-- be sought first relative to the working directory, then relative
147+-- be sought first relative to the working directory, then in the
148+-- media bag, then relative
139149-- to the user data directory (if the first parameter is 'Just'
140150-- a directory), and finally relative to pandoc's default data
141151-- directory.
142−makeSelfContained :: Maybe FilePath -> String -> IO String
143−makeSelfContained userdata inp = do
152+makeSelfContained :: MediaBag -> Maybe FilePath -> String -> IO String
153+makeSelfContained media userdata inp = do
144154 let tags = parseTags inp
145− out' <- mapM (convertTag userdata) tags
155+ out' <- mapM (convertTag media userdata) tags
146156 return $ renderTags' out'
147−
src/Text/Pandoc/Writers/EPUB.hs+1−1
@@ -793,7 +793,7 @@ transformInline opts mediaRef (Image lab (src,tit)) = do
793793 return $ Image lab (newsrc, tit)
794794transformInline opts _ (x@(Math _ _))
795795 | WebTeX _ <- writerHTMLMathMethod opts = do
796− raw <- makeSelfContained Nothing $ writeHtmlInline opts x
796+ raw <- makeSelfContained M.empty Nothing $ writeHtmlInline opts x
797797 return $ RawInline (Format "html") raw
798798transformInline opts mediaRef (RawInline fmt raw)
799799 | fmt == Format "html" = do