{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Text.Pandoc.MediaBag (
MediaBag,
deleteMedia,
lookupMedia,
insertMedia,
mediaDirectory,
mediaItems
) where
import qualified Data.ByteString.Lazy as BL
import Data.Data (Data)
import qualified Data.Map as M
import Data.Maybe (fromMaybe)
import Data.Typeable (Typeable)
import System.FilePath
import qualified System.FilePath.Posix as Posix
import Text.Pandoc.MIME (MimeType, getMimeTypeDef)
newtype MediaBag = MediaBag (M.Map [FilePath] (MimeType, BL.ByteString))
deriving (b -> MediaBag -> MediaBag
NonEmpty MediaBag -> MediaBag
MediaBag -> MediaBag -> MediaBag
(MediaBag -> MediaBag -> MediaBag)
-> (NonEmpty MediaBag -> MediaBag)
-> (forall b. Integral b => b -> MediaBag -> MediaBag)
-> Semigroup MediaBag
forall b. Integral b => b -> MediaBag -> MediaBag
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> MediaBag -> MediaBag
$cstimes :: forall b. Integral b => b -> MediaBag -> MediaBag
sconcat :: NonEmpty MediaBag -> MediaBag
$csconcat :: NonEmpty MediaBag -> MediaBag
<> :: MediaBag -> MediaBag -> MediaBag
$c<> :: MediaBag -> MediaBag -> MediaBag
Semigroup, Semigroup MediaBag
MediaBag
Semigroup MediaBag
-> MediaBag
-> (MediaBag -> MediaBag -> MediaBag)
-> ([MediaBag] -> MediaBag)
-> Monoid MediaBag
[MediaBag] -> MediaBag
MediaBag -> MediaBag -> MediaBag
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [MediaBag] -> MediaBag
$cmconcat :: [MediaBag] -> MediaBag
mappend :: MediaBag -> MediaBag -> MediaBag
$cmappend :: MediaBag -> MediaBag -> MediaBag
mempty :: MediaBag
$cmempty :: MediaBag
$cp1Monoid :: Semigroup MediaBag
Monoid, Typeable MediaBag
DataType
Constr
Typeable MediaBag
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MediaBag -> c MediaBag)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MediaBag)
-> (MediaBag -> Constr)
-> (MediaBag -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MediaBag))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MediaBag))
-> ((forall b. Data b => b -> b) -> MediaBag -> MediaBag)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r)
-> (forall u. (forall d. Data d => d -> u) -> MediaBag -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> MediaBag -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag)
-> Data MediaBag
MediaBag -> DataType
MediaBag -> Constr
(forall b. Data b => b -> b) -> MediaBag -> MediaBag
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MediaBag -> c MediaBag
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MediaBag
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> MediaBag -> u
forall u. (forall d. Data d => d -> u) -> MediaBag -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MediaBag
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MediaBag -> c MediaBag
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MediaBag)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MediaBag)
$cMediaBag :: Constr
$tMediaBag :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
gmapMp :: (forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
gmapM :: (forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> MediaBag -> m MediaBag
gmapQi :: Int -> (forall d. Data d => d -> u) -> MediaBag -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> MediaBag -> u
gmapQ :: (forall d. Data d => d -> u) -> MediaBag -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> MediaBag -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> MediaBag -> r
gmapT :: (forall b. Data b => b -> b) -> MediaBag -> MediaBag
$cgmapT :: (forall b. Data b => b -> b) -> MediaBag -> MediaBag
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MediaBag)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c MediaBag)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c MediaBag)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c MediaBag)
dataTypeOf :: MediaBag -> DataType
$cdataTypeOf :: MediaBag -> DataType
toConstr :: MediaBag -> Constr
$ctoConstr :: MediaBag -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MediaBag
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c MediaBag
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MediaBag -> c MediaBag
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> MediaBag -> c MediaBag
$cp1Data :: Typeable MediaBag
Data, Typeable)
instance Show MediaBag where
show :: MediaBag -> String
show MediaBag
bag = String
"MediaBag " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(String, MimeType, Int)] -> String
forall a. Show a => a -> String
show (MediaBag -> [(String, MimeType, Int)]
mediaDirectory MediaBag
bag)
deleteMedia :: FilePath
-> MediaBag
-> MediaBag
deleteMedia :: String -> MediaBag -> MediaBag
deleteMedia String
fp (MediaBag Map [String] (MimeType, ByteString)
mediamap) =
Map [String] (MimeType, ByteString) -> MediaBag
MediaBag (Map [String] (MimeType, ByteString) -> MediaBag)
-> Map [String] (MimeType, ByteString) -> MediaBag
forall a b. (a -> b) -> a -> b
$ [String]
-> Map [String] (MimeType, ByteString)
-> Map [String] (MimeType, ByteString)
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (String -> [String]
splitDirectories String
fp) Map [String] (MimeType, ByteString)
mediamap
insertMedia :: FilePath
-> Maybe MimeType
-> BL.ByteString
-> MediaBag
-> MediaBag
insertMedia :: String -> Maybe MimeType -> ByteString -> MediaBag -> MediaBag
insertMedia String
fp Maybe MimeType
mbMime ByteString
contents (MediaBag Map [String] (MimeType, ByteString)
mediamap) =
Map [String] (MimeType, ByteString) -> MediaBag
MediaBag ([String]
-> (MimeType, ByteString)
-> Map [String] (MimeType, ByteString)
-> Map [String] (MimeType, ByteString)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (String -> [String]
splitDirectories String
fp) (MimeType
mime, ByteString
contents) Map [String] (MimeType, ByteString)
mediamap)
where mime :: MimeType
mime = MimeType -> Maybe MimeType -> MimeType
forall a. a -> Maybe a -> a
fromMaybe MimeType
fallback Maybe MimeType
mbMime
fallback :: MimeType
fallback = case ShowS
takeExtension String
fp of
String
".gz" -> String -> MimeType
getMimeTypeDef (String -> MimeType) -> String -> MimeType
forall a b. (a -> b) -> a -> b
$ ShowS
dropExtension String
fp
String
_ -> String -> MimeType
getMimeTypeDef String
fp
lookupMedia :: FilePath
-> MediaBag
-> Maybe (MimeType, BL.ByteString)
lookupMedia :: String -> MediaBag -> Maybe (MimeType, ByteString)
lookupMedia String
fp (MediaBag Map [String] (MimeType, ByteString)
mediamap) = [String]
-> Map [String] (MimeType, ByteString)
-> Maybe (MimeType, ByteString)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (String -> [String]
splitDirectories String
fp) Map [String] (MimeType, ByteString)
mediamap
mediaDirectory :: MediaBag -> [(FilePath, MimeType, Int)]
mediaDirectory :: MediaBag -> [(String, MimeType, Int)]
mediaDirectory (MediaBag Map [String] (MimeType, ByteString)
mediamap) =
([String]
-> (MimeType, ByteString)
-> [(String, MimeType, Int)]
-> [(String, MimeType, Int)])
-> [(String, MimeType, Int)]
-> Map [String] (MimeType, ByteString)
-> [(String, MimeType, Int)]
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
M.foldrWithKey (\[String]
fp (MimeType
mime,ByteString
contents) ->
(([String] -> String
Posix.joinPath [String]
fp, MimeType
mime, Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Int) -> Int64 -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> Int64
BL.length ByteString
contents)(String, MimeType, Int)
-> [(String, MimeType, Int)] -> [(String, MimeType, Int)]
forall a. a -> [a] -> [a]
:)) [] Map [String] (MimeType, ByteString)
mediamap
mediaItems :: MediaBag -> [(FilePath, MimeType, BL.ByteString)]
mediaItems :: MediaBag -> [(String, MimeType, ByteString)]
mediaItems (MediaBag Map [String] (MimeType, ByteString)
mediamap) =
([String]
-> (MimeType, ByteString)
-> [(String, MimeType, ByteString)]
-> [(String, MimeType, ByteString)])
-> [(String, MimeType, ByteString)]
-> Map [String] (MimeType, ByteString)
-> [(String, MimeType, ByteString)]
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
M.foldrWithKey (\[String]
fp (MimeType
mime,ByteString
contents) ->
(([String] -> String
Posix.joinPath [String]
fp, MimeType
mime, ByteString
contents)(String, MimeType, ByteString)
-> [(String, MimeType, ByteString)]
-> [(String, MimeType, ByteString)]
forall a. a -> [a] -> [a]
:)) [] Map [String] (MimeType, ByteString)
mediamap