{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.OSC1337
( module Data.OSC1337,
LatexStr (..),
latex,
math,
)
where
import Codec.Picture
import Codec.Picture.Png (encodePng)
import qualified Data.ByteString as B
import Data.ByteString (ByteString)
import Data.ByteString.Base64 (encode)
import qualified Data.ByteString.Char8 as BC
import Data.ByteString.Lazy (toStrict)
import Data.Sixel.Internal
import System.IO.Unsafe (unsafePerformIO)
data OSCCmd
= Start
| End
| FileName String
| Size Int
| Width Int
| Height Int
| PreserveAspectRatio Int
| Inline Int
| Align String
| MimeType String
| ImageDat String
deriving (Eq)
instance Show OSCCmd where
show = \case
Start -> "\ESC]1337;"
End -> "\a"
Size s -> "size=" ++ show s ++ ";"
Width s -> "width=" ++ show s ++ ";"
Height s -> "height=" ++ show s ++ ";"
PreserveAspectRatio s -> "preserveAspectRatio=" ++ show s ++ ";"
Inline s -> "inline=" ++ show s ++ ";"
Align s -> "align=" ++ s ++ ";"
MimeType s -> "type=" ++ s ++ ";"
ImageDat s -> BC.unpack $ encode $ BC.pack s
instance {-# OVERLAPS #-} Show [OSCCmd] where
show xs = concat $ map show xs
newtype OSCImage = OSCImage {toOSCString :: String} deriving (Eq)
instance Show OSCImage where
show (OSCImage img) = img
class ToOSC a where
toOSC :: a -> OSCImage
putOSC :: a -> IO ()
instance {-# OVERLAPS #-} (Show a) => ToOSC a where
toOSC xs = OSCImage $ show xs
putOSC xs = putStrLn $ show xs
img2osc :: Image PixelRGB8 -> ByteString
img2osc img =
let (Image w h _) = img
dat = toStrict $ encodePng img
in B.concat
[ "\ESC]1337;File=name=",
encode "display.png",
";",
"width=" <> BC.pack (show w) <> "px;",
"height=" <> BC.pack (show h) <> "px;",
"inline=1;:",
encode dat,
"\a"
]
instance {-# OVERLAPS #-} ToOSC DynamicImage where
toOSC dimg = toOSC $ convertRGB8 dimg
putOSC img = putOSC $ convertRGB8 img
instance {-# OVERLAPS #-} ToOSC (Image PixelRGB8) where
toOSC img = OSCImage (BC.unpack $ img2osc img)
putOSC img = B.putStr $ img2osc img
putImage :: FilePath -> IO ()
putImage file = do
readImage file >>= \case
Left err -> print err
Right img -> putOSC img
instance Show LatexStr where
show str = show $ toOSC str
instance ToOSC LatexStr where
toOSC str = unsafePerformIO $ do
latex2img str >>= \case
Left err -> error err
Right img -> return $ toOSC img
putOSC img = putStr $ show $ toOSC img