    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE TupleSections     #-}
    {- |
       Module      : Text.Pandoc.SelfContained
       Copyright   : Copyright (C) 2011-2020 John MacFarlane
       License     : GNU GPL, version 2 or above

       Maintainer  : John MacFarlane <jgm@berkeley.edu>
       Stability   : alpha
       Portability : portable

    Functions for converting an HTML file into one that can be viewed
    offline, by incorporating linked images, CSS, and scripts into
    the HTML using data URIs.
    -}
    module Text.Pandoc.SelfContained ( makeDataURI, makeSelfContained ) where
    import Codec.Compression.GZip as Gzip
    import Control.Applicative ((<|>))
    import Control.Monad.Except (throwError)
    import Control.Monad.Trans (lift)
    import Data.ByteString (ByteString)
    import Data.ByteString.Base64
    import qualified Data.ByteString.Char8 as B
    import qualified Data.ByteString.Lazy as L
    import qualified Data.Text as T
    import Data.Char (isAlphaNum, isAscii)
    import Network.URI (escapeURIString)
    import System.FilePath (takeDirectory, takeExtension, (</>))
    import Text.HTML.TagSoup
    import Text.Pandoc.Class.PandocMonad (PandocMonad (..), fetchItem,
                                          getInputFiles, report, setInputFiles)
    import Text.Pandoc.Error
    import Text.Pandoc.Logging
    import Text.Pandoc.MIME (MimeType)
    import Text.Pandoc.Shared (isURI, renderTags', trim)
    import Text.Pandoc.UTF8 (toString, toText, fromText)
    import Text.Parsec (ParsecT, runParserT)
    import qualified Text.Parsec as P

    isOk :: Char -> Bool
    isOk :: Char -> Bool
    isOk c :: Char
    c = Char -> Bool
    isAscii Char
    c Bool -> Bool -> Bool
    && Char -> Bool
    isAlphaNum Char
    c

    makeDataURI :: (MimeType, ByteString) -> T.Text
    makeDataURI :: (MimeType, ByteString) -> MimeType
    makeDataURI (mime :: MimeType
    mime, raw :: ByteString
    raw) =
      if Bool
    textual
         then "data:" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType
    mime' MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> "," MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> String -> MimeType
    T.pack ((Char -> Bool) -> String -> String
    escapeURIString Char -> Bool
    isOk (ByteString -> String
    toString ByteString
    raw))
         else "data:" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType
    mime' MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ";base64," MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ByteString -> MimeType
    toText (ByteString -> ByteString
    encode ByteString
    raw)
      where textual :: Bool
    textual = "text/" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime
            mime' :: MimeType
    mime' = if Bool
    textual Bool -> Bool -> Bool
    && (Char -> Bool) -> MimeType -> Bool
    T.any (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == ';') MimeType
    mime
                       then MimeType
    mime MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ";charset=utf-8"
                       else MimeType
    mime  -- mime type already has charset

    convertTags :: PandocMonad m => [Tag T.Text] -> m [Tag T.Text]
    convertTags :: [Tag MimeType] -> m [Tag MimeType]
    convertTags [] = [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
    convertTags (t :: Tag MimeType
    t@TagOpen{}:ts :: [Tag MimeType]
    ts)
      | MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "data-external" Tag MimeType
    t MimeType -> MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    == "1" = (Tag MimeType
    tTag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :) ([Tag MimeType] -> [Tag MimeType])
    -> m [Tag MimeType] -> m [Tag MimeType]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
    convertTags (t :: Tag MimeType
    t@(TagOpen tagname :: MimeType
    tagname as :: [Attribute MimeType]
    as):ts :: [Tag MimeType]
    ts)
      | MimeType
    tagname MimeType -> [MimeType] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem`
         ["img", "embed", "video", "input", "audio", "source", "track",
          "section"] = do
           [Attribute MimeType]
    as' <- (Attribute MimeType -> m (Attribute MimeType))
    -> [Attribute MimeType] -> m [Attribute MimeType]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM Attribute MimeType -> m (Attribute MimeType)
    forall a (m :: * -> *).
    (Eq a, IsString a, PandocMonad m) =>
    (a, MimeType) -> m (a, MimeType)
    processAttribute [Attribute MimeType]
    as
           [Tag MimeType]
    rest <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
           [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $ MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen MimeType
    tagname [Attribute MimeType]
    as' Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
      where processAttribute :: (a, MimeType) -> m (a, MimeType)
    processAttribute (x :: a
    x,y :: MimeType
    y) =
               if a
    x a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` ["src", "data-src", "href", "poster", "data-background-image"]
                  then do
                    MimeType
    enc <- MimeType -> MimeType -> m MimeType
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> MimeType -> m MimeType
    getDataURI (MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "type" Tag MimeType
    t) MimeType
    y
                    (a, MimeType) -> m (a, MimeType)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    x, MimeType
    enc)
                  else (a, MimeType) -> m (a, MimeType)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a
    x,MimeType
    y)
    convertTags (t :: Tag MimeType
    t@(TagOpen "script" as :: [Attribute MimeType]
    as):TagClose "script":ts :: [Tag MimeType]
    ts) =
      case MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "src" Tag MimeType
    t of
           ""  -> (Tag MimeType
    tTag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :) ([Tag MimeType] -> [Tag MimeType])
    -> m [Tag MimeType] -> m [Tag MimeType]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
           src :: MimeType
    src -> do
               let typeAttr :: MimeType
    typeAttr = MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "type" Tag MimeType
    t
               Either MimeType (MimeType, ByteString)
    res <- MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    getData MimeType
    typeAttr MimeType
    src
               [Tag MimeType]
    rest <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
               case Either MimeType (MimeType, ByteString)
    res of
                    Left dataUri :: MimeType
    dataUri -> [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $ MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "script"
                         (("src",MimeType
    dataUri) Attribute MimeType -> [Attribute MimeType] -> [Attribute MimeType]
    forall a. a -> [a] -> [a]
    : [(MimeType
    x,MimeType
    y) | (x :: MimeType
    x,y :: MimeType
    y) <- [Attribute MimeType]
    as, MimeType
    x MimeType -> MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "src"]) Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :
                         MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagClose "script" Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
                    Right (mime :: MimeType
    mime, bs :: ByteString
    bs)
                      | ("text/javascript" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime Bool -> Bool -> Bool
    ||
                         "application/javascript" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime Bool -> Bool -> Bool
    ||
                         "application/x-javascript" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime) Bool -> Bool -> Bool
    &&
                         Bool -> Bool
    not ("</script" ByteString -> ByteString -> Bool
    `B.isInfixOf` ByteString
    bs) ->
                         [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $
                           MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "script" [("type", MimeType
    typeAttr)|Bool -> Bool
    not (MimeType -> Bool
    T.null MimeType
    typeAttr)]
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagText (ByteString -> MimeType
    toText ByteString
    bs)
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagClose "script"
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
                      | Bool
    otherwise ->
                           [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return  ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $ MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "script"
                             (("src",(MimeType, ByteString) -> MimeType
    makeDataURI (MimeType
    mime, ByteString
    bs)) Attribute MimeType -> [Attribute MimeType] -> [Attribute MimeType]
    forall a. a -> [a] -> [a]
    :
                              [(MimeType
    x,MimeType
    y) | (x :: MimeType
    x,y :: MimeType
    y) <- [Attribute MimeType]
    as, MimeType
    x MimeType -> MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "src"]) Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :
                            MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagClose "script" Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
    convertTags (t :: Tag MimeType
    t@(TagOpen "link" as :: [Attribute MimeType]
    as):ts :: [Tag MimeType]
    ts) =
      case MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "href" Tag MimeType
    t of
           ""  -> (Tag MimeType
    tTag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :) ([Tag MimeType] -> [Tag MimeType])
    -> m [Tag MimeType] -> m [Tag MimeType]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
           src :: MimeType
    src -> do
               Either MimeType (MimeType, ByteString)
    res <- MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    getData (MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "type" Tag MimeType
    t) MimeType
    src
               case Either MimeType (MimeType, ByteString)
    res of
                    Left dataUri :: MimeType
    dataUri -> do
                      [Tag MimeType]
    rest <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
                      [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $ MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "link"
                         (("href",MimeType
    dataUri) Attribute MimeType -> [Attribute MimeType] -> [Attribute MimeType]
    forall a. a -> [a] -> [a]
    : [(MimeType
    x,MimeType
    y) | (x :: MimeType
    x,y :: MimeType
    y) <- [Attribute MimeType]
    as, MimeType
    x MimeType -> MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "href"]) Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :
                         [Tag MimeType]
    rest
                    Right (mime :: MimeType
    mime, bs :: ByteString
    bs)
                      | "text/css" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime
                        Bool -> Bool -> Bool
    && MimeType -> Bool
    T.null (MimeType -> Tag MimeType -> MimeType
    forall str.
    (Show str, Eq str, StringLike str) =>
    str -> Tag str -> str
    fromAttrib "media" Tag MimeType
    t)
                        Bool -> Bool -> Bool
    && Bool -> Bool
    not ("</" ByteString -> ByteString -> Bool
    `B.isInfixOf` ByteString
    bs) -> do
                          [Tag MimeType]
    rest <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $
                                     (Tag MimeType -> Bool) -> [Tag MimeType] -> [Tag MimeType]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Tag MimeType -> Tag MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    ==MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagClose "link") [Tag MimeType]
    ts
                          [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $
                           MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "style" [("type", "text/css")] -- see #5725
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagText (ByteString -> MimeType
    toText ByteString
    bs)
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : MimeType -> Tag MimeType
    forall str. str -> Tag str
    TagClose "style"
                           Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
                      | Bool
    otherwise -> do
                          [Tag MimeType]
    rest <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts
                          [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([Tag MimeType] -> m [Tag MimeType])
    -> [Tag MimeType] -> m [Tag MimeType]
    forall a b. (a -> b) -> a -> b
    $ MimeType -> [Attribute MimeType] -> Tag MimeType
    forall str. str -> [Attribute str] -> Tag str
    TagOpen "link"
                           (("href",(MimeType, ByteString) -> MimeType
    makeDataURI (MimeType
    mime, ByteString
    bs)) Attribute MimeType -> [Attribute MimeType] -> [Attribute MimeType]
    forall a. a -> [a] -> [a]
    :
                             [(MimeType
    x,MimeType
    y) | (x :: MimeType
    x,y :: MimeType
    y) <- [Attribute MimeType]
    as, MimeType
    x MimeType -> MimeType -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "href"]) Tag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    : [Tag MimeType]
    rest
    convertTags (t :: Tag MimeType
    t:ts :: [Tag MimeType]
    ts) = (Tag MimeType
    tTag MimeType -> [Tag MimeType] -> [Tag MimeType]
    forall a. a -> [a] -> [a]
    :) ([Tag MimeType] -> [Tag MimeType])
    -> m [Tag MimeType] -> m [Tag MimeType]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    ts

    cssURLs :: PandocMonad m
            => FilePath -> ByteString -> m ByteString
    cssURLs :: String -> ByteString -> m ByteString
    cssURLs d :: String
    d orig :: ByteString
    orig = do
      Either ParseError ByteString
    res <- ParsecT ByteString () m ByteString
    -> () -> String -> ByteString -> m (Either ParseError ByteString)
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> u -> String -> s -> m (Either ParseError a)
    runParserT (String -> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ParsecT ByteString () m ByteString
    parseCSSUrls String
    d) () "css" ByteString
    orig
      case Either ParseError ByteString
    res of
           Left e :: ParseError
    e    -> do
             LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ MimeType -> LogMessage
    CouldNotParseCSS (MimeType -> LogMessage) -> MimeType -> LogMessage
    forall a b. (a -> b) -> a -> b
    $ String -> MimeType
    T.pack (String -> MimeType) -> String -> MimeType
    forall a b. (a -> b) -> a -> b
    $ ParseError -> String
    forall a. Show a => a -> String
    show ParseError
    e
             ByteString -> m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    orig
           Right bs :: ByteString
    bs  -> ByteString -> m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    bs

    parseCSSUrls :: PandocMonad m
                 => FilePath -> ParsecT ByteString () m ByteString
    parseCSSUrls :: String -> ParsecT ByteString () m ByteString
    parseCSSUrls d :: String
    d = [ByteString] -> ByteString
    B.concat ([ByteString] -> ByteString)
    -> ParsecT ByteString () m [ByteString]
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m [ByteString]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    P.many
      (ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m ByteString
    pCSSWhite ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m ByteString
    pCSSComment ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> String -> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ParsecT ByteString () m ByteString
    pCSSImport String
    d ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> String -> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ParsecT ByteString () m ByteString
    pCSSUrl String
    d ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m ByteString
    pCSSOther)

    pCSSImport :: PandocMonad m
               => FilePath -> ParsecT ByteString () m ByteString
    pCSSImport :: String -> ParsecT ByteString () m ByteString
    pCSSImport d :: String
    d = ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (ParsecT ByteString () m ByteString
     -> ParsecT ByteString () m ByteString)
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall a b. (a -> b) -> a -> b
    $ do
      String -> ParsecT ByteString () m String
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m String
    P.string "@import"
      ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces
      Either ByteString (MimeType, ByteString)
    res <- (ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m (MimeType, ByteString)
    pQuoted ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m (MimeType, ByteString)
    pUrl) ParsecT ByteString () m (MimeType, ByteString)
    -> ((MimeType, ByteString)
        -> ParsecT
             ByteString () m (Either ByteString (MimeType, ByteString)))
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String
    -> (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    String
    -> (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    handleCSSUrl String
    d
      ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces
      Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char ';'
      ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces
      case Either ByteString (MimeType, ByteString)
    res of
           Left b :: ByteString
    b       -> ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> ParsecT ByteString () m ByteString)
    -> ByteString -> ParsecT ByteString () m ByteString
    forall a b. (a -> b) -> a -> b
    $ String -> ByteString
    B.pack "@import " ByteString -> ByteString -> ByteString
    forall a. Semigroup a => a -> a -> a
    <> ByteString
    b
           Right (_, b :: ByteString
    b) -> ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    b

    -- Note: some whitespace in CSS is significant, so we can't collapse it!
    pCSSWhite :: PandocMonad m => ParsecT ByteString () m ByteString
    pCSSWhite :: ParsecT ByteString () m ByteString
    pCSSWhite = Char -> ByteString
    B.singleton (Char -> ByteString)
    -> ParsecT ByteString () m Char
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT ByteString () m Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    P.space ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m () -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces

    pCSSComment :: PandocMonad m => ParsecT ByteString () m ByteString
    pCSSComment :: ParsecT ByteString () m ByteString
    pCSSComment = ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (ParsecT ByteString () m ByteString
     -> ParsecT ByteString () m ByteString)
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall a b. (a -> b) -> a -> b
    $ do
      String -> ParsecT ByteString () m String
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m String
    P.string "/*"
      ParsecT ByteString () m Char
    -> ParsecT ByteString () m String -> ParsecT ByteString () m String
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    P.manyTill ParsecT ByteString () m Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    P.anyChar (ParsecT ByteString () m String -> ParsecT ByteString () m String
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (String -> ParsecT ByteString () m String
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m String
    P.string "*/"))
      ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    B.empty

    pCSSOther :: PandocMonad m => ParsecT ByteString () m ByteString
    pCSSOther :: ParsecT ByteString () m ByteString
    pCSSOther =
      (String -> ByteString
    B.pack (String -> ByteString)
    -> ParsecT ByteString () m String
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT ByteString () m Char -> ParsecT ByteString () m String
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m [a]
    P.many1 (String -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m Char
    P.noneOf "u/ \n\r\t")) ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
      (Char -> ByteString
    B.singleton (Char -> ByteString)
    -> ParsecT ByteString () m Char
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char 'u') ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|>
      (Char -> ByteString
    B.singleton (Char -> ByteString)
    -> ParsecT ByteString () m Char
    -> ParsecT ByteString () m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char '/')

    pCSSUrl :: PandocMonad m
            => FilePath -> ParsecT ByteString () m ByteString
    pCSSUrl :: String -> ParsecT ByteString () m ByteString
    pCSSUrl d :: String
    d = ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (ParsecT ByteString () m ByteString
     -> ParsecT ByteString () m ByteString)
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m ByteString
    forall a b. (a -> b) -> a -> b
    $ do
      Either ByteString (MimeType, ByteString)
    res <- ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *).
    PandocMonad m =>
    ParsecT ByteString () m (MimeType, ByteString)
    pUrl ParsecT ByteString () m (MimeType, ByteString)
    -> ((MimeType, ByteString)
        -> ParsecT
             ByteString () m (Either ByteString (MimeType, ByteString)))
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String
    -> (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    String
    -> (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    handleCSSUrl String
    d
      case Either ByteString (MimeType, ByteString)
    res of
           Left b :: ByteString
    b -> ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    b
           Right (mt :: MimeType
    mt,b :: ByteString
    b) -> do
             let enc :: MimeType
    enc = (MimeType, ByteString) -> MimeType
    makeDataURI (MimeType
    mt, ByteString
    b)
             ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ByteString -> ParsecT ByteString () m ByteString)
    -> ByteString -> ParsecT ByteString () m ByteString
    forall a b. (a -> b) -> a -> b
    $ MimeType -> ByteString
    fromText (MimeType -> ByteString) -> MimeType -> ByteString
    forall a b. (a -> b) -> a -> b
    $ "url(" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType
    enc MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ")"

    pQuoted :: PandocMonad m
            => ParsecT ByteString () m (T.Text, ByteString)
    pQuoted :: ParsecT ByteString () m (MimeType, ByteString)
    pQuoted = ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (ParsecT ByteString () m (MimeType, ByteString)
     -> ParsecT ByteString () m (MimeType, ByteString))
    -> ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall a b. (a -> b) -> a -> b
    $ do
      Char
    quote <- String -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m Char
    P.oneOf "\"'"
      MimeType
    url <- String -> MimeType
    T.pack (String -> MimeType)
    -> ParsecT ByteString () m String
    -> ParsecT ByteString () m MimeType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT ByteString () m Char
    -> ParsecT ByteString () m Char -> ParsecT ByteString () m String
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    P.manyTill ParsecT ByteString () m Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    P.anyChar (Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char Char
    quote)
      let fallback :: ByteString
    fallback = MimeType -> ByteString
    fromText (MimeType -> ByteString) -> MimeType -> ByteString
    forall a b. (a -> b) -> a -> b
    $ Char -> MimeType
    T.singleton Char
    quote MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType -> MimeType
    trim MimeType
    url MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> Char -> MimeType
    T.singleton Char
    quote
      (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MimeType
    url, ByteString
    fallback)

    pUrl :: PandocMonad m
         => ParsecT ByteString () m (T.Text, ByteString)
    pUrl :: ParsecT ByteString () m (MimeType, ByteString)
    pUrl = ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    P.try (ParsecT ByteString () m (MimeType, ByteString)
     -> ParsecT ByteString () m (MimeType, ByteString))
    -> ParsecT ByteString () m (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall a b. (a -> b) -> a -> b
    $ do
      String -> ParsecT ByteString () m String
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m String
    P.string "url("
      ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces
      Maybe Char
    quote <- Maybe Char
    -> ParsecT ByteString () m (Maybe Char)
    -> ParsecT ByteString () m (Maybe Char)
    forall s (m :: * -> *) t a u.
    Stream s m t =>
    a -> ParsecT s u m a -> ParsecT s u m a
    P.option Maybe Char
    forall a. Maybe a
    Nothing (Char -> Maybe Char
    forall a. a -> Maybe a
    Just (Char -> Maybe Char)
    -> ParsecT ByteString () m Char
    -> ParsecT ByteString () m (Maybe Char)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    String -> ParsecT s u m Char
    P.oneOf "\"'")
      MimeType
    url <- String -> MimeType
    T.pack (String -> MimeType)
    -> ParsecT ByteString () m String
    -> ParsecT ByteString () m MimeType
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT ByteString () m Char
    -> ParsecT ByteString () m Char -> ParsecT ByteString () m String
    forall s (m :: * -> *) t u a end.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
    P.manyTill ParsecT ByteString () m Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    P.anyChar (ParsecT ByteString () m Char
    -> (Char -> ParsecT ByteString () m Char)
    -> Maybe Char
    -> ParsecT ByteString () m Char
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ParsecT ByteString () m Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m a
    P.lookAhead (Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char ')')) Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char Maybe Char
    quote)
      ParsecT ByteString () m ()
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
    P.spaces
      Char -> ParsecT ByteString () m Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    P.char ')'
      let fallback :: ByteString
    fallback = MimeType -> ByteString
    fromText ("url(" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType -> (Char -> MimeType) -> Maybe Char -> MimeType
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Char -> MimeType
    T.singleton Maybe Char
    quote MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType -> MimeType
    trim MimeType
    url MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <>
                                MimeType -> (Char -> MimeType) -> Maybe Char -> MimeType
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe "" Char -> MimeType
    T.singleton Maybe Char
    quote MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ")")
      (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MimeType
    url, ByteString
    fallback)

    handleCSSUrl :: PandocMonad m
                 => FilePath -> (T.Text, ByteString)
                 -> ParsecT ByteString () m
                      (Either ByteString (MimeType, ByteString))
    handleCSSUrl :: String
    -> (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    handleCSSUrl d :: String
    d (url :: MimeType
    url, fallback :: ByteString
    fallback) =
      case (Char -> Bool) -> String -> String
    escapeURIString (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /='|') (MimeType -> String
    T.unpack (MimeType -> String) -> MimeType -> String
    forall a b. (a -> b) -> a -> b
    $ MimeType -> MimeType
    trim MimeType
    url) of
          '#':_ -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either ByteString (MimeType, ByteString)
     -> ParsecT
          ByteString () m (Either ByteString (MimeType, ByteString)))
    -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Either ByteString (MimeType, ByteString)
    forall a b. a -> Either a b
    Left ByteString
    fallback
          'd':'a':'t':'a':':':_ -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either ByteString (MimeType, ByteString)
     -> ParsecT
          ByteString () m (Either ByteString (MimeType, ByteString)))
    -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Either ByteString (MimeType, ByteString)
    forall a b. a -> Either a b
    Left ByteString
    fallback
          u :: String
    u ->  do let url' :: MimeType
    url' = if MimeType -> Bool
    isURI (String -> MimeType
    T.pack String
    u) then String -> MimeType
    T.pack String
    u else String -> MimeType
    T.pack (String
    d String -> String -> String
    </> String
    u)
                   Either MimeType (MimeType, ByteString)
    res <- m (Either MimeType (MimeType, ByteString))
    -> ParsecT ByteString () m (Either MimeType (MimeType, ByteString))
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m (Either MimeType (MimeType, ByteString))
     -> ParsecT
          ByteString () m (Either MimeType (MimeType, ByteString)))
    -> m (Either MimeType (MimeType, ByteString))
    -> ParsecT ByteString () m (Either MimeType (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    getData "" MimeType
    url'
                   case Either MimeType (MimeType, ByteString)
    res of
                        Left uri :: MimeType
    uri -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either ByteString (MimeType, ByteString)
     -> ParsecT
          ByteString () m (Either ByteString (MimeType, ByteString)))
    -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Either ByteString (MimeType, ByteString)
    forall a b. a -> Either a b
    Left (MimeType -> ByteString
    fromText (MimeType -> ByteString) -> MimeType -> ByteString
    forall a b. (a -> b) -> a -> b
    $ "url(" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType
    uri MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> ")")
                        Right (mt' :: MimeType
    mt', raw :: ByteString
    raw) -> do
                          -- note that the downloaded CSS may
                          -- itself contain url(...).
                          (mt :: MimeType
    mt, b :: ByteString
    b) <- if "text/css" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mt'
                                        -- see #5725: in HTML5, content type
                                        -- isn't allowed on style type attribute
                                        then ("text/css",) (ByteString -> (MimeType, ByteString))
    -> ParsecT ByteString () m ByteString
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> ByteString -> ParsecT ByteString () m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> m ByteString
    cssURLs String
    d ByteString
    raw
                                        else (MimeType, ByteString)
    -> ParsecT ByteString () m (MimeType, ByteString)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MimeType
    mt', ByteString
    raw)
                          Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either ByteString (MimeType, ByteString)
     -> ParsecT
          ByteString () m (Either ByteString (MimeType, ByteString)))
    -> Either ByteString (MimeType, ByteString)
    -> ParsecT
         ByteString () m (Either ByteString (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ (MimeType, ByteString) -> Either ByteString (MimeType, ByteString)
    forall a b. b -> Either a b
    Right (MimeType
    mt, ByteString
    b)

    getDataURI :: PandocMonad m => MimeType -> T.Text -> m T.Text
    getDataURI :: MimeType -> MimeType -> m MimeType
    getDataURI mimetype :: MimeType
    mimetype src :: MimeType
    src = do
      Either MimeType (MimeType, ByteString)
    res <- MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    getData MimeType
    mimetype MimeType
    src
      case Either MimeType (MimeType, ByteString)
    res of
           Left uri :: MimeType
    uri -> MimeType -> m MimeType
    forall (m :: * -> *) a. Monad m => a -> m a
    return MimeType
    uri
           Right x :: (MimeType, ByteString)
    x  -> MimeType -> m MimeType
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MimeType -> m MimeType) -> MimeType -> m MimeType
    forall a b. (a -> b) -> a -> b
    $ (MimeType, ByteString) -> MimeType
    makeDataURI (MimeType, ByteString)
    x

    getData :: PandocMonad m
            => MimeType -> T.Text
            -> m (Either T.Text (MimeType, ByteString))
    getData :: MimeType -> MimeType -> m (Either MimeType (MimeType, ByteString))
    getData mimetype :: MimeType
    mimetype src :: MimeType
    src
      | "data:" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    src = Either MimeType (MimeType, ByteString)
    -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either MimeType (MimeType, ByteString)
     -> m (Either MimeType (MimeType, ByteString)))
    -> Either MimeType (MimeType, ByteString)
    -> m (Either MimeType (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ MimeType -> Either MimeType (MimeType, ByteString)
    forall a b. a -> Either a b
    Left MimeType
    src -- already data: uri
      | Bool
    otherwise = do
          let ext :: MimeType
    ext = MimeType -> MimeType
    T.toLower (MimeType -> MimeType) -> MimeType -> MimeType
    forall a b. (a -> b) -> a -> b
    $ String -> MimeType
    T.pack (String -> MimeType) -> String -> MimeType
    forall a b. (a -> b) -> a -> b
    $ String -> String
    takeExtension (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $ MimeType -> String
    T.unpack MimeType
    src
          (raw :: ByteString
    raw, respMime :: Maybe MimeType
    respMime) <- MimeType -> m (ByteString, Maybe MimeType)
    forall (m :: * -> *).
    PandocMonad m =>
    MimeType -> m (ByteString, Maybe MimeType)
    fetchItem MimeType
    src
          let raw' :: ByteString
    raw' = if MimeType
    ext MimeType -> [MimeType] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [".gz", ".svgz"]
                     then [ByteString] -> ByteString
    B.concat ([ByteString] -> ByteString) -> [ByteString] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ ByteString -> [ByteString]
    L.toChunks (ByteString -> [ByteString]) -> ByteString -> [ByteString]
    forall a b. (a -> b) -> a -> b
    $ ByteString -> ByteString
    Gzip.decompress (ByteString -> ByteString) -> ByteString -> ByteString
    forall a b. (a -> b) -> a -> b
    $ [ByteString] -> ByteString
    L.fromChunks [ByteString
    raw]
                     else ByteString
    raw
          MimeType
    mime <- case (MimeType
    mimetype, Maybe MimeType
    respMime) of
                    ("",Nothing) -> PandocError -> m MimeType
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError (PandocError -> m MimeType) -> PandocError -> m MimeType
    forall a b. (a -> b) -> a -> b
    $ MimeType -> PandocError
    PandocSomeError
                      (MimeType -> PandocError) -> MimeType -> PandocError
    forall a b. (a -> b) -> a -> b
    $ "Could not determine mime type for `" MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> MimeType
    src MimeType -> MimeType -> MimeType
    forall a. Semigroup a => a -> a -> a
    <> "'"
                    (x :: MimeType
    x, Nothing) -> MimeType -> m MimeType
    forall (m :: * -> *) a. Monad m => a -> m a
    return MimeType
    x
                    (_, Just x :: MimeType
    x ) -> MimeType -> m MimeType
    forall (m :: * -> *) a. Monad m => a -> m a
    return MimeType
    x
          ByteString
    result <- if "text/css" MimeType -> MimeType -> Bool
    `T.isPrefixOf` MimeType
    mime
                    then do
                      [String]
    oldInputs <- m [String]
    forall (m :: * -> *). PandocMonad m => m [String]
    getInputFiles
                      [String] -> m ()
    forall (m :: * -> *). PandocMonad m => [String] -> m ()
    setInputFiles [MimeType -> String
    T.unpack MimeType
    src]
                      ByteString
    res <- String -> ByteString -> m ByteString
    forall (m :: * -> *).
    PandocMonad m =>
    String -> ByteString -> m ByteString
    cssURLs (String -> String
    takeDirectory (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $ MimeType -> String
    T.unpack MimeType
    src) ByteString
    raw'
                      [String] -> m ()
    forall (m :: * -> *). PandocMonad m => [String] -> m ()
    setInputFiles [String]
    oldInputs
                      ByteString -> m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    res
                   else ByteString -> m ByteString
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    raw'
          Either MimeType (MimeType, ByteString)
    -> m (Either MimeType (MimeType, ByteString))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either MimeType (MimeType, ByteString)
     -> m (Either MimeType (MimeType, ByteString)))
    -> Either MimeType (MimeType, ByteString)
    -> m (Either MimeType (MimeType, ByteString))
    forall a b. (a -> b) -> a -> b
    $ (MimeType, ByteString) -> Either MimeType (MimeType, ByteString)
    forall a b. b -> Either a b
    Right (MimeType
    mime, ByteString
    result)

    -- | Convert HTML into self-contained HTML, incorporating images,
    -- scripts, and CSS using data: URIs.
    makeSelfContained :: PandocMonad m => T.Text -> m T.Text
    makeSelfContained :: MimeType -> m MimeType
    makeSelfContained inp :: MimeType
    inp = do
      let tags :: [Tag MimeType]
    tags = MimeType -> [Tag MimeType]
    forall str. StringLike str => str -> [Tag str]
    parseTags MimeType
    inp
      [Tag MimeType]
    out' <- [Tag MimeType] -> m [Tag MimeType]
    forall (m :: * -> *).
    PandocMonad m =>
    [Tag MimeType] -> m [Tag MimeType]
    convertTags [Tag MimeType]
    tags
      MimeType -> m MimeType
    forall (m :: * -> *) a. Monad m => a -> m a
    return (MimeType -> m MimeType) -> MimeType -> m MimeType
    forall a b. (a -> b) -> a -> b
    $ [Tag MimeType] -> MimeType
    renderTags' [Tag MimeType]
    out'