ihaskell-magic-0.3.0.0: IHaskell/Display/Magic.hs
{-# LANGUAGE ViewPatterns, TypeSynonymInstances, FlexibleInstances #-}
module IHaskell.Display.Magic () where
import IHaskell.Display
import Magic
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import qualified Data.ByteString.Base64 as Base64
import qualified Data.ByteString.Char8 as Char
import qualified Data.ByteString.UTF8 as B
import Text.Read
import Data.Char
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import IHaskell.IPython.Types (MimeType(MimeSvg))
import Data.ByteString.UTF8
instance IHaskellDisplay T.Text where
display = display . T.encodeUtf8
instance IHaskellDisplay B.ByteString where
display x = do
m <- magicOpen []
magicLoadDefault m
f <- B.unsafeUseAsCStringLen x (magicCString m)
return $ Display [withClass (parseMagic f) x]
b64 :: B.ByteString -> String
b64 = Char.unpack . Base64.encode
withClass :: MagicClass -> B.ByteString -> DisplayData
withClass SVG = DisplayData MimeSvg . T.decodeUtf8
withClass (PNG w h) = png w h . T.decodeUtf8 . Base64.encode
withClass JPG = jpg 400 300 . T.decodeUtf8 . Base64.encode
withClass HTML = html . B.toString
withClass LaTeX = latex . B.toString
withClass _ = plain . B.toString
{- | parse the string produced by magic.
>>> parseMagic "LaTeX 2e document, ASCII text, with very long lines"
LaTeX
>>> parseMagic "PNG image data, 480 x 480, 8-bit/color RGB, non-interlaced"
PNG 480 480
>>> parseMagic "HTML document, ASCII text, with very long lines"
HTML
>>> parseMagic "JPEG image data, JFIF standard 1.01"
JPG
-}
parseMagic :: String -> MagicClass
parseMagic f =
case words f of
"SVG":_ -> SVG
"PNG":_image:_data:(readMaybe -> Just w):_x:(readMaybe . takeWhile isDigit -> Just h):_ -> PNG w
h
"LaTeX":_ -> LaTeX
"HTML":_ -> HTML
"JPEG":_ -> JPG
_ -> Unknown
data MagicClass = SVG
| PNG Int Int
| JPG
| HTML
| LaTeX
| Unknown
deriving Show