diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2009 Iavor S. Diatchki
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Language/Haskell/Colorize.hs b/Language/Haskell/Colorize.hs
new file mode 100644
--- /dev/null
+++ b/Language/Haskell/Colorize.hs
@@ -0,0 +1,169 @@
+module Language.Haskell.Colorize where
+
+import qualified Language.Haskell.Lexer as L
+import System.Console.ANSI
+
+-- | The different types of that we recognize.
+data Token
+  = Comment     -- ^ Comment
+  | Reserved    -- ^ Reserved word
+  | ReservedOp  -- ^ Reserved operator
+  | Var         -- ^ Variables
+  | VarOp       -- ^ Variable operatros
+  | Con         -- ^ Constructors
+  | ConOp       -- ^ Constructor operators
+  | Special     -- ^ Special syntax  (e.g., parens,brackets)
+  | IntLit      -- ^ Integer lieterals
+  | FloatLit    -- ^ Floating point literals
+  | CharLit     -- ^ Character literals
+  | StringLit   -- ^ String literals
+
+-- | The type of functions that specify how to render a value.
+type Style = Token -> String -> ShowS
+
+render :: Style -> String -> ShowS
+render how prog k = foldr step k (L.lexerPass0 prog)
+  where
+  step (y,(_,x)) =
+    case y of
+      L.Varid              -> how Var x
+      L.Conid              -> how Con x
+      L.Varsym             -> how VarOp x
+      L.Consym             -> how ConOp x
+      L.Reservedid
+          | x == "_"       -> how Var x
+          | otherwise      -> how Reserved x
+      L.Reservedop         -> how ReservedOp x
+      L.Special            -> how Special x
+      L.IntLit             -> how IntLit x
+      L.FloatLit           -> how FloatLit x
+      L.CharLit            -> how CharLit x
+      L.StringLit          -> how StringLit x
+      L.Qvarid             -> how Var x
+      L.Qconid             -> how Con x
+      L.Qvarsym            -> how VarOp x
+      L.Qconsym            -> how ConOp x
+      L.NestedCommentStart -> how Comment x
+      L.NestedComment      -> how Comment x
+      L.LiterateComment    -> how Comment x
+      L.Commentstart       -> how Comment x
+      L.Comment            -> how Comment x
+
+      _                    -> (x ++)
+
+-- | Annotates tokens with ANSI escape sequences, suitable for a dark termianl
+ansiDark :: Style
+ansiDark t = case t of
+  Comment        -> bright Cyan
+  Reserved       -> bright Green
+  ReservedOp     -> bright Yellow
+  VarOp          -> bright Yellow
+  ConOp          -> bright Yellow
+  IntLit         -> bright Magenta
+  FloatLit       -> bright Magenta
+  CharLit        -> bright Magenta
+  StringLit      -> bright Magenta
+  _              -> (++)
+
+  where bright x xs k = setSGRCode [ SetConsoleIntensity BoldIntensity
+                                   , SetColor Foreground Vivid x
+                                   ]
+                ++ xs ++ setSGRCode [Reset] ++ k
+
+
+-- | Annotates tokens with ANSI escape sequences, suitable for a dark termianl
+ansiLight :: Style
+ansiLight t = case t of
+  Comment        -> dark Blue
+  Reserved       -> dark Green
+  ReservedOp     -> dark Red
+  VarOp          -> dark Red
+  ConOp          -> dark Red
+  IntLit         -> dark Magenta
+  FloatLit       -> dark Magenta
+  CharLit        -> dark Magenta
+  StringLit      -> dark Magenta
+  _              -> (++)
+
+  where dark x xs k = setSGRCode [ SetConsoleIntensity FaintIntensity
+                                 , SetColor Foreground Dull x
+                                 ]
+                ++ xs ++ setSGRCode [Reset] ++ k
+
+
+
+{-
+
+-- | Annotates tokens with HTML tags.
+html :: Style
+html = Style
+  { comment        = tag "comment"
+  , reserved       = tag "reseved"
+  , reservedOp     = tag "resevedOp"
+  , var            = tag "var"
+  , varOp          = tag "varOp"
+  , con            = tag "con"
+  , conOp          = tag "conOp"
+  , intLit         = tag "intLit"
+  , floatLit       = tag "floatLit"
+  , charLit        = tag "charLit"
+  , stringLit      = tag "stringLit"
+  , special        = tag "special"
+
+  , prefix         = showString "<html><head>"
+                   . showString css
+                   . showString "</head><body><pre>"
+  , postfix        = showString "</pre></body></html>"
+  }
+  where tag x cs  = "<span class='" ++ x ++ "'>"
+                                ++ concatMap esc cs ++ "</span>"
+        esc c     = case c of
+                      '<' -> "&lt;"
+                      '>' -> "&gt;"
+                      '&' -> "&amp;"
+                      _   -> [c]
+        css       = unlines
+                  [ "<style type='text/css' rel='stylesheet'>"
+                  , ".comment { color: blue }"
+                  , "</style>"
+                  ]
+
+
+--------------------------------------------------------------------------------
+
+
+getOptions :: IO Options
+getOptions =
+  do (fs,non_opt,errs) <- getOpt Permute flags `fmap` getArgs
+     case (non_opt,errs) of
+       ([],[]) -> return (foldr ($) defaultOptions fs)
+       _       -> mapM_ (hPutStrLn stderr) errs >> showUsage
+
+-- | Print usage info and quit
+showUsage :: IO a
+showUsage = do hPutStrLn stderr (usageInfo "Available options:" flags)
+               exitFailure
+
+flags :: [ OptDescr (Options -> Options) ]
+flags = [ Option []       ["html"]  (NoArg $ \o -> o { optStyle = HTML })
+          "Generate HTML output"
+        , Option []       ["ansi"]  (NoArg $ \o -> o { optStyle = ANSI })
+          "Generate ANSI output (default)"
+        , Option ['h']    ["help"]  (NoArg $ \o -> o { optHelp = True })
+          "Display this help."
+        ]
+
+data OptStyle = ANSI | HTML
+
+data Options = Options
+  { optStyle :: OptStyle
+  , optHelp  :: Bool
+  }
+
+defaultOptions :: Options
+defaultOptions = Options
+  { optStyle = ANSI
+  , optHelp  = False
+  }
+-}
+
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,57 @@
+module Main where
+
+import Language.Haskell.Colorize
+import System.Console.GetOpt
+import System.Environment(getArgs)
+import System.IO
+import System.Exit(exitFailure)
+import Control.Monad(when)
+
+main :: IO ()
+main =
+  do opts <- getOptions
+     when (optHelp opts) showUsage
+     let style = case optStyle opts of
+                   ANSILight  -> ansiLight
+                   ANSIDark   -> ansiDark
+     interact (\xs -> render style xs "")
+
+
+getOptions :: IO Options
+getOptions =
+  do (fs,non_opt,errs) <- getOpt Permute flags `fmap` getArgs
+     case (non_opt,errs) of
+       ([],[]) -> return (foldr ($) defaultOptions fs)
+       _       -> mapM_ (hPutStrLn stderr) errs >> showUsage
+
+-- | Print usage info and quit
+showUsage :: IO a
+showUsage = do hPutStrLn stderr (usageInfo "Available options:" flags)
+               exitFailure
+
+flags :: [ OptDescr (Options -> Options) ]
+flags = [ Option []       ["ansi-dark"]
+          (NoArg $ \o -> o { optStyle = ANSIDark })
+          "Generate ANSI output for a dark terminal (default)"
+        , Option []       ["ansi-light"]
+          (NoArg $ \o -> o { optStyle = ANSILight })
+          "Generate ANSI output for a light terminal"
+        , Option ['h']    ["help"]
+          (NoArg $ \o -> o { optHelp = True })
+          "Display this help."
+        ]
+
+data OptStyle = ANSILight | ANSIDark
+
+data Options = Options
+  { optStyle :: OptStyle
+  , optHelp  :: Bool
+  }
+
+defaultOptions :: Options
+defaultOptions = Options
+  { optStyle = ANSIDark
+  , optHelp  = False
+  }
+
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain
diff --git a/colorize-haskell.cabal b/colorize-haskell.cabal
new file mode 100644
--- /dev/null
+++ b/colorize-haskell.cabal
@@ -0,0 +1,33 @@
+name:           colorize-haskell
+version:        1.0.0
+license:        BSD3
+license-file:   LICENSE
+author:         Iavor S. Diatchki
+maintainer:     iavor.diatchki@gmail.com
+homepage:       http://github.com/yav/hscolor
+build-type:     Simple
+cabal-version:  >= 1.2
+synopsis:       Highligt Haskell source
+description:    TODO
+category:       Development
+
+library
+  build-depends:
+    base >= 3 && < 5,
+    haskell-lexer,
+    ansi-terminal
+  exposed-modules:
+    Language.Haskell.Colorize
+  ghc-options:
+    -Wall -O2
+
+
+executable hscolor
+    main-is:         Main.hs
+    -- because we cannot depend on self:
+    build-depends:
+      base >= 3 && < 5,
+      haskell-lexer,
+      ansi-terminal
+    ghc-options:     -Wall -O2
+
