diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,3 +3,7 @@
 ## 0.1.0.0 -- 2020-05-17
 
 * First version.
+
+## 0.1.2.0 -- 2020-05-19
+
+* Support for Latex
diff --git a/csrc/sixel.c b/csrc/sixel.c
--- a/csrc/sixel.c
+++ b/csrc/sixel.c
@@ -16,7 +16,7 @@
 
 int
 img2sixel(unsigned char* buf, unsigned char* img,int width,int height){
-  int i,j;
+  int i,j,k;
   int p=0;
   int c;
   int prev = (100 << 16 ) | (100 << 8 ) | 100;
@@ -66,6 +66,24 @@
 	putnum(buf,&p,g);
 	buf[p++] = ';';
 	putnum(buf,&p,b);
+      } else {
+	int num;
+	for(k=i+1;k<width;k++){
+	  int pix = (j*width+k)*3;
+	  int r = img[pix]*101/256;
+	  int g = img[pix+1]*101/256;
+	  int b = img[pix+2]*101/256;
+	  int nxt = (r << 16) | (g << 8) | b;
+	  if(nxt!=cur){
+	    break;
+	  }
+	}
+	num = (k-i)-1;
+	if(num > 3){
+	  buf[p++] = '!';
+	  putnum(buf,&p,num+1);
+	  i=k-1;
+	}
       }
       buf[p++] = (1 << (j%6))+0x3f;
       prev = cur;
diff --git a/demo.png b/demo.png
Binary files a/demo.png and b/demo.png differ
diff --git a/sixel.cabal b/sixel.cabal
--- a/sixel.cabal
+++ b/sixel.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                sixel
-version:             0.1.1.1
+version:             0.1.2.0
 synopsis:            Sixel library to show images in a terminal emulator
 description:         Sixel can show graphics on a terminal emulator. This library is developed to showing images on ghci.
 license:             BSD3
@@ -23,6 +23,8 @@
                      , JuicyPixels
                      , vector
                      , bytestring
+                     , process
+                     , temporary
   c-sources:           csrc/sixel.c
 
 executable sixel-exe
diff --git a/src/Data/Sixel.hs b/src/Data/Sixel.hs
--- a/src/Data/Sixel.hs
+++ b/src/Data/Sixel.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE LambdaCase #-}
 
 module Data.Sixel where
@@ -14,30 +15,35 @@
 import Foreign.C.Types
 import Foreign.ForeignPtr
 import Foreign.Ptr
-import System.IO.Unsafe
+import System.IO.Temp (withSystemTempDirectory)
+import System.IO.Unsafe (unsafePerformIO)
+import System.Process (readProcessWithExitCode)
 
 foreign import ccall "bufsize" c_bufsize :: CInt -> CInt -> IO CInt
 
 foreign import ccall "img2sixel" c_img2sixel :: Ptr () -> Ptr () -> CInt -> CInt -> IO CInt
 
-img2sixel :: Image PixelRGB8 -> String
-img2sixel img = BC.unpack $ img2sixel' img
+newtype SixelImage = SixelImage {toSixelString :: String} deriving (Eq)
 
-img2sixel' :: Image PixelRGB8 -> ByteString
-img2sixel' img = unsafePerformIO $ do
-  let (Image w h vec) = img
-  bsize <- c_bufsize (fromIntegral w) (fromIntegral h)
-  let (sptr, _) = V.unsafeToForeignPtr0 vec
-  B.createAndTrim (fromIntegral bsize) $ \dst -> do
-    withForeignPtr sptr $ \src -> do
-      len <- c_img2sixel (castPtr dst) (castPtr src) (fromIntegral w) (fromIntegral h)
-      return (fromIntegral len)
+data LatexStr
+  = LatexStr
+      { toLatexStr :: String,
+        strSize :: Float
+      }
+  deriving (Eq)
 
-newtype SixelImage = SixelImage {toSixelString :: String} deriving (Eq)
+latex :: String -> LatexStr
+latex str = LatexStr str 2.5
 
+math :: String -> LatexStr
+math str = LatexStr ("$"++str++"$") 2.5
+
 instance Show SixelImage where
   show (SixelImage img) = img
 
+instance Show LatexStr where
+  show str = show $ toSixel str
+
 type ColorNumber = Word8
 
 type PixelPattern = Word8
@@ -49,9 +55,9 @@
 data SixelCmd
   = Start Int Int Int
   | End
-  | Size Int Int Int Int
+  | Size Int Int Width Height
   | ColorMapRGB ColorNumber Word8 Word8 Word8
-  | ColorMapHLS ColorNumber Int Int Int
+  | ColorMapHLS ColorNumber Int Word8 Word8
   | Color ColorNumber
   | Sixel PixelPattern
   | Repeat Int PixelPattern
@@ -75,23 +81,57 @@
 instance {-# OVERLAPS #-} Show [SixelCmd] where
   show xs = concat $ map show xs
 
-numDigits :: (Integral a, Ord a, Num a) => a -> Int
-numDigits n
-  | n < 10 = 1
-  | otherwise = numDigits (n `div` 10) + 1
-
 class ToSixel a where
   toSixel :: a -> SixelImage
+  putSixel :: a -> IO ()
 
-instance ToSixel [SixelCmd] where
+instance {-# OVERLAPS #-} (Show a) => ToSixel a where
+  toSixel xs = SixelImage $ show xs
+  putSixel xs = putStrLn $ show xs
+
+instance {-# OVERLAPS #-} ToSixel [SixelCmd] where
   toSixel xs = SixelImage (concat $ map show xs)
+  putSixel xs = putStr $ concat $ map show xs
 
-instance ToSixel DynamicImage where
+instance {-# OVERLAPS #-} ToSixel DynamicImage where
   toSixel dimg = toSixel $ convertRGB8 dimg
+  putSixel img = BC.putStr $ img2sixel $ convertRGB8 img
 
-instance ToSixel (Image PixelRGB8) where
-  toSixel img = SixelImage (img2sixel img)
+instance {-# OVERLAPS #-} ToSixel (Image PixelRGB8) where
+  toSixel img = SixelImage (BC.unpack $ img2sixel img)
+  putSixel img = BC.putStr $ img2sixel img
 
+instance {-# OVERLAPS #-} ToSixel SixelImage where
+  toSixel = id
+  putSixel img = putStr $ show img
+
+latexStr :: String -> Float -> String
+latexStr str size =
+  "\\documentclass[border=2pt]{standalone}"
+    ++ "\\usepackage{amsmath}"
+    ++ "\\usepackage{graphicx}"
+    ++ "\\usepackage{varwidth}"
+    ++ "\\begin{document}"
+    ++ "\\begin{varwidth}{\\linewidth}"
+    ++ "\\scalebox{"
+    ++ show size
+    ++ "}{"
+    ++ str
+    ++ "}"
+    ++ "\\end{varwidth}"
+    ++ "\\end{document}"
+
+instance ToSixel LatexStr where
+  toSixel (LatexStr str size) = unsafePerformIO $ do
+    withSystemTempDirectory "sixel" $ \dir -> do
+      writeFile (dir ++ "/sixel.tex") (latexStr str size)
+      (_,outlog,errlog) <- readProcessWithExitCode "pdflatex" ["-output-directory="++dir ,dir ++ "/sixel.tex"] ""
+      readProcessWithExitCode "convert" [dir ++ "/sixel.pdf", "-quality", "90", dir ++ "/sixel.png"] ""
+      readImage (dir ++ "/sixel.png") >>= \case
+        Left err -> error $ "can not read sixel.png. // " ++ errlog ++ " // " ++ outlog
+        Right img -> return $ toSixel img
+  putSixel img = putStr $ show $ toSixel img
+
 --  toSixel img = SixelImage (show (toSixelCmds img))
 
 toSixelCmds :: Image PixelRGB8 -> [SixelCmd]
@@ -130,37 +170,30 @@
             [footer]
           ]
    in pixels
-
-pixel2colorMap :: Image PixelRGB8 -> Int -> Int -> SixelCmd
-pixel2colorMap img i j =
-  let p@(PixelRGB8 r g b) = pixelAt img i j
-      rr = fromIntegral $ ((fromIntegral r :: Int) * 101) `div` 256
-      gg = fromIntegral $ ((fromIntegral g :: Int) * 101) `div` 256
-      bb = fromIntegral $ ((fromIntegral b :: Int) * 101) `div` 256
-   in ColorMapRGB 0 rr gg bb
+  where
+    pixel2colorMap :: Image PixelRGB8 -> Int -> Int -> SixelCmd
+    pixel2colorMap img i j =
+      let p@(PixelRGB8 r g b) = pixelAt img i j
+          rr = fromIntegral $ ((fromIntegral r :: Int) * 101) `div` 256
+          gg = fromIntegral $ ((fromIntegral g :: Int) * 101) `div` 256
+          bb = fromIntegral $ ((fromIntegral b :: Int) * 101) `div` 256
+       in ColorMapRGB 0 rr gg bb
 
--- putImage :: FilePath -> IO ()
--- putImage file = do
---   readImage file >>= \case
---     Left err -> print err
---     Right img -> putStr $ toSixelString $ toSixel img
+img2sixel :: Image PixelRGB8 -> ByteString
+img2sixel img = unsafePerformIO $ do
+  let (Image w h vec) = img
+  bsize <- c_bufsize (fromIntegral w) (fromIntegral h)
+  let (sptr, _) = V.unsafeToForeignPtr0 vec
+  B.createAndTrim (fromIntegral bsize) $ \dst -> do
+    withForeignPtr sptr $ \src -> do
+      len <- c_img2sixel (castPtr dst) (castPtr src) (fromIntegral w) (fromIntegral h)
+      return (fromIntegral len)
 
+-- | Display sixel image via ByteString
+-- putStr of String is really slow on ghci. (Compiled version is not so slow.)
+-- To improve perfomance of rendering on ghci, this function uses putStr of ByteString.
 putImage :: FilePath -> IO ()
 putImage file = do
   readImage file >>= \case
     Left err -> print err
-    Right img -> BC.putStr $ img2sixel' $ convertRGB8 img
-
-demo :: [SixelCmd]
-demo =
-  [ Start 0 0 8,
-    Size 1 1 100 100,
-    ColorMapRGB 0 50 0 0,
-    Color 0,
-    Sixel 1,
-    Sixel 2,
-    Sixel 4,
-    Sixel 8,
-    Sixel 16,
-    End
-  ]
+    Right img -> putSixel img
