git.iko.soy/typeable/pandoc
on master help sign in
SelfContained: Convert all url()s in css to data: uris.
commit012684375117c95f086f21c44d9b88660ec1e4c7 authorJohn MacFarlane <fiddlosopher@gmail.com> dateSun 4 Dec 2011, 12:19 (15 years ago) parentfb5f9a9
1 file changed+22−29
src/Text/Pandoc/SelfContained.hs+22−29
src/Text/Pandoc/SelfContained.hs+22−29
@@ -37,7 +37,7 @@ import Network.HTTP
3737import Data.ByteString.Base64
3838import qualified Data.ByteString.Char8 as B
3939import Data.ByteString (ByteString)
40−import Data.ByteString.UTF8 (toString)
40+import Data.ByteString.UTF8 (toString, fromString)
4141import System.FilePath (takeExtension, dropExtension, takeDirectory, (</>))
4242import Data.Char (toLower, isAscii, isAlphaNum)
4343import Codec.Compression.GZip as Gzip
@@ -206,67 +206,60 @@ convertTag userdata t@(TagOpen "img" as) =
206206 case fromAttrib "src" t of
207207 [] -> return t
208208 src -> do
209− (raw, mime) <- getRaw userdata t src
209+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
210210 let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)
211211 return $ TagOpen "img" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
212212convertTag userdata t@(TagOpen "video" as) =
213213 case fromAttrib "src" t of
214214 [] -> return t
215215 src -> do
216− (raw, mime) <- getRaw userdata t src
216+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
217217 let enc = "data:" ++ mime ++ ";base64," ++ toString (encode raw)
218218 return $ TagOpen "video" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
219219convertTag userdata t@(TagOpen "script" as) =
220220 case fromAttrib "src" t of
221221 [] -> return t
222222 src -> do
223− (raw, mime) <- getRaw userdata t src
223+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
224224 let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
225225 return $ TagOpen "script" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
226226convertTag userdata t@(TagOpen "link" as) =
227227 case fromAttrib "href" t of
228228 [] -> return t
229229 src -> do
230− (raw, mime) <- getRaw userdata t src
230+ (raw, mime) <- getRaw userdata (fromAttrib "type" t) src
231231 let enc = "data:" ++ mime ++ "," ++ escapeURIString isOk (toString raw)
232232 return $ TagOpen "link" (("href",enc) : [(x,y) | (x,y) <- as, x /= "href"])
233233convertTag _ t = return t
234234
235−cssImports :: Maybe FilePath -> FilePath -> ByteString -> IO ByteString
236−cssImports userdata d orig =
237− case B.breakSubstring "@import" orig of
235+cssURLs :: Maybe FilePath -> FilePath -> ByteString -> IO ByteString
236+cssURLs userdata d orig =
237+ case B.breakSubstring "url(" orig of
238238 (x,y) | B.null y -> return orig
239239 | otherwise -> do
240− rest <- handleImport userdata d (B.drop 7 y)
241− >>= cssImports userdata d
242− return $ x `B.append` rest
240+ let (u,v) = B.breakSubstring ")" $ B.drop 4 y
241+ let url = toString
242+ $ case B.take 1 u of
243+ "\"" -> B.takeWhile (/='"') $ B.drop 1 u
244+ _ -> u
245+ (raw, mime) <- getRaw userdata "" (d </> url)
246+ rest <- cssURLs userdata d v
247+ let enc = "data:" `B.append` fromString mime `B.append`
248+ ";base64," `B.append` (encode raw)
249+ return $ x `B.append` "url(" `B.append` enc `B.append` rest
243250
244−-- @import url("blah");
245−-- @import url(blah);
246−-- @import "blah";
247−handleImport :: Maybe FilePath -> FilePath -> ByteString -> IO ByteString
248−handleImport userdata d x =
249− fmap (`B.append` rest) (getItem userdata $ d </> url)
250− where lparenOrQuote c = c == '(' || c == '"'
251− rparenOrQuote c = c == ')' || c == '"'
252− url = toString
253− $ B.takeWhile (not . rparenOrQuote)
254− $ B.dropWhile lparenOrQuote
255− $ B.dropWhile (not . lparenOrQuote) x
256− rest = B.drop 1 $ B.dropWhile (/= ';') x
257−
258−getRaw :: Maybe FilePath -> Tag String -> String -> IO (ByteString, String)
259−getRaw userdata t src = do
251+getRaw :: Maybe FilePath -> String -> String -> IO (ByteString, String)
252+getRaw userdata mimetype src = do
260253 let ext = map toLower $ takeExtension src
261254 let (ext',decomp) = if ext == ".gz"
262255 then (takeExtension $ dropExtension src, B.concat . L.toChunks . Gzip.decompress . L.fromChunks . (:[]))
263256 else (ext, id)
264− let mime = case fromAttrib "type" t of
257+ let mime = case mimetype of
265258 [] -> mimeTypeFor ext'
266259 x -> x
267260 raw <- getItem userdata src
268261 result <- if mime == "text/css"
269− then cssImports userdata (takeDirectory src) $ decomp raw
262+ then cssURLs userdata (takeDirectory src) $ decomp raw
270263 else return $ decomp raw
271264 return (result, mime)
272265