diff --git a/Graphics/Rendering/HSparklines.hs b/Graphics/Rendering/HSparklines.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Rendering/HSparklines.hs
@@ -0,0 +1,179 @@
+---------------------------------------------------------------
+-- |
+-- Module      : Graphics.Rendering.HSparklines
+-- Copyright   : (c) Hitesh Jasani, 2008
+-- License     : BSD3
+--
+-- Maintainer  : Hitesh Jasani <hitesh.jasani@gmail.com>
+-- Stability   : experimental
+-- Portability : portable
+--
+-- Created     : 2008-02-26
+-- Version     : 0.1
+--
+-- Sparklines implementation in Haskell.  Sparklines are
+-- mini graphs inspired by Edward Tufte.
+--
+-- > dp :: [Float]
+-- > dp = [24,21,32.3,24,15,34,43,55,57,72,74,75,73,72,55,44]
+-- >
+-- > make barSpark dp >>= savePngFile "bar_spark.png"
+-- >
+---------------------------------------------------------------
+
+module Graphics.Rendering.HSparklines
+    (
+     -- * Types
+     SparkOptions(..)
+    ,rgb
+     -- * Drawing functions
+    ,make
+    ,smoothSpark
+    ,barSpark
+    -- * Saving functions
+    ,savePngFile
+    ,encodePngAsDataUrl
+    ) where
+
+
+import Codec.Binary.Base64 ( encode )
+import Control.Monad
+import Data.ByteString ( unpack )
+import Data.List
+import Data.Ord
+import Graphics.GD
+
+
+
+make :: SparkOptions -> [Float] -> IO Image
+make so@(SmoothOptions {}) dp = renderSmooth so dp
+make so@(BarOptions {})    dp = renderBar so dp
+
+
+data SparkOptions = SmoothOptions
+  {
+   step :: Int                  -- ^ step size
+  ,height :: Int                -- ^ graph height (pixels)
+  ,limits :: (Int,Int)          -- ^ data point limits
+  ,bgColor :: Color             -- ^ background color
+  ,minColor :: Color            -- ^ color of minimum datapoint
+  ,maxColor :: Color            -- ^ color of maximum datapoint
+  ,lastColor :: Color           -- ^ color of last datapoint
+  ,minMarker :: Bool            -- ^ display minimum marker
+  ,maxMarker :: Bool            -- ^ display maximum marker
+  ,lastMarker :: Bool           -- ^ display last marker
+  }
+                  | BarOptions
+  {
+   step :: Int                  -- ^ step size
+  ,height :: Int                -- ^ graph height (pixels)
+  ,limits :: (Int,Int)          -- ^ data point limits
+  ,bgColor :: Color             -- ^ background color
+  ,minColor :: Color            -- ^ color of minimum datapoint
+  ,maxColor :: Color            -- ^ color of maximum datapoint
+  ,lastColor :: Color           -- ^ color of last datapoint
+  ,minMarker :: Bool            -- ^ display minimum marker
+  ,maxMarker :: Bool            -- ^ display maximum marker
+  ,lastMarker :: Bool           -- ^ display last marker
+  }
+                  deriving (Show)
+
+
+smoothSpark :: SparkOptions
+smoothSpark = SmoothOptions
+  {
+   step = 2
+  ,height = 20
+  ,limits = (0,100)
+  ,bgColor = white
+  ,minColor = red
+  ,maxColor = green
+  ,lastColor = blue
+  ,minMarker = True
+  ,maxMarker = True
+  ,lastMarker = True
+  }
+
+
+barSpark :: SparkOptions
+barSpark = BarOptions
+  {
+   step = 2
+  ,height = 20
+  ,limits = (0,100)
+  ,bgColor = white
+  ,minColor = red
+  ,maxColor = green
+  ,lastColor = blue
+  ,minMarker = True
+  ,maxMarker = True
+  ,lastMarker = True
+  }
+
+
+renderSmooth :: SparkOptions -> [Float] -> IO Image
+renderSmooth opt ds = do
+  let w = 4 + (step opt) * (length ds - 1)
+      h = height opt 
+      dmin = fst (limits opt)
+      dmax = snd (limits opt)
+      coords = zip [1,(1+(step opt))..(1+(step opt)*(length ds))]
+                   [h - round( (y-(fi dmin)) / ((fi (dmax-dmin+1)) / (fi (h-4))) )
+                        | y <- ds ]
+      minpt = maximumBy (comparing snd) coords -- because y increases as we go down
+      maxpt = minimumBy (comparing snd) coords
+      endpt = last coords
+
+  img <- newImage (w,h)
+  drawFilledRectangle (0,0) (w,h) (bgColor opt) img
+  zipWithM_ (\p1 p2 -> antiAliased (drawLine p1 p2) grey img)
+            coords (drop 1 coords)
+  when (minMarker opt) (uncurry drawFilledRectangle (boxpt minpt) (minColor opt) img)
+  when (maxMarker opt) (uncurry drawFilledRectangle (boxpt maxpt) (maxColor opt) img)
+  when (lastMarker opt) (uncurry drawFilledRectangle (boxpt endpt) (lastColor opt)
+                         img)
+  return img
+
+
+renderBar :: SparkOptions -> [Float] -> IO Image
+renderBar opt ds = do
+  let w = 4 + (step opt) * (length ds - 1) + bw2 * length ds
+      h = height opt
+      dmin = fst (limits opt)
+      dmax = snd (limits opt)
+      bw = 1
+      bw2 = 2 * bw
+      coords = zip [1,(1+(step opt)+bw2)..(1+((step opt)+bw2)*(length ds))]
+                   [h - round( (y-(fi dmin)) / ((fi (dmax-dmin+1)) / (fi (h-4))) )
+                        | y <- ds ]
+      minpt = maximumBy (comparing snd) coords -- because y increases as we go down
+      maxpt = minimumBy (comparing snd) coords
+      endpt = last coords
+
+  img <- newImage (w,h)
+  drawFilledRectangle (0,0) (w,h) (bgColor opt) img
+  forM_ coords $ \(x,y) ->
+    antiAliased (drawFilledRectangle (x-bw,y) (x+bw,h)) grey img
+  when (minMarker opt) (uncurry drawFilledRectangle (boxpt minpt) (minColor opt) img)
+  when (maxMarker opt) (uncurry drawFilledRectangle (boxpt maxpt) (maxColor opt) img)
+  when (lastMarker opt) (uncurry drawFilledRectangle (boxpt endpt) (lastColor opt)
+                         img)
+  return img
+
+
+encodePngAsDataUrl :: Image -> IO String
+encodePngAsDataUrl img = savePngByteString img >>= return . encode . unpack
+
+fi :: (Num b, Integral a) => a -> b
+fi x = fromIntegral x
+
+boxpt :: (Num a) => (a,a) -> ((a,a),(a,a))
+boxpt (x,y) = (,) (x-1,y-1) (x+1,y+1)
+
+white,grey,red,green,blue :: Color
+white = rgb 0xff 0xff 0xff
+grey = rgb 0x88 0x88 0x88
+red = rgb 0xff 0x00 0x00
+green = rgb 0x00 0xff 0x00
+blue = rgb 0x00 0x00 0xff
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) Hitesh Jasani <hitesh.jasani@gmail.com>
+
+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 CONTRIBUTORS ``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/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,39 @@
+
+INTRO
+
+Sparklines are high content to size ratio minigraphs inspired by Edward Tufte.
+
+The focus of a sparkline is to provide additional context inline with text
+so users can do more informed analysis and make better decisions.  To make
+them fit with inline text, sparklines are generally small (100px x 30px)
+and dispense with axis labels and units.
+
+
+REFERENCES
+
+o http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&topic_id=1
+o http://bitworking.org/projects/sparklines/
+
+
+
+
+INSTALL
+
+  % runhaskell Setup.lhs configure
+  % runhaskell Setup.lhs build
+  % runhaskell Setup.lhs haddock
+  % sudo runhaskell Setup.lhs install
+
+
+NOTES
+
+You may encounter problems building the documentation if you're using
+a version of haddock before version 2.0.0.0.
+
+
+ACKNOWLEDGEMENTS
+
+Joe Gregorio's Python implementation of Sparklines served as an inspiration
+for doing a Haskell version.  He's done some good work, make sure to check
+out his site http://bitworking.org/
+
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,9 @@
+#!/usr/bin/env runhaskell
+
+> module Main where
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
+
+
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,17 @@
+
+FLAGS = -Wall -Werror -O2 -i..
+LIBS = -lgd -L/opt/local/lib
+SRCS = $(wildcard *.hs)
+EXES = $(subst .hs,.exe,$(SRCS))
+
+.PHONY: all clean
+
+default: $(EXES)
+
+all: $(EXES)
+
+%.exe: %.hs
+	ghc --make $(FLAGS) $< -o $@ $(LIBS)
+
+clean:
+	-rm *.png *.exe *.o *.hi *~ dataurl.html
diff --git a/examples/bar.hs b/examples/bar.hs
new file mode 100644
--- /dev/null
+++ b/examples/bar.hs
@@ -0,0 +1,14 @@
+
+import Graphics.Rendering.HSparklines
+
+dp :: [Float]
+dp = [24,21,32.3,24,15,34,43,55,57,72,74,75,73,72,55,44]
+
+main :: IO ()
+main = do
+  make (barSpark) dp >>= savePngFile "bar_spark.png"
+  make (barSpark {step = 5}) dp >>= savePngFile "bar_spark_s5.png"
+  make (barSpark {bgColor = rgb 0xee 0xee 0xee}) dp >>=
+    savePngFile "bar_spark_bg.png"
+  make (barSpark {bgColor = rgb 0xee 0xee 0xee, step = 5, minMarker = False}) dp
+    >>= savePngFile "bar_spark_bg_s5.png"
diff --git a/examples/bar.html b/examples/bar.html
new file mode 100644
--- /dev/null
+++ b/examples/bar.html
@@ -0,0 +1,10 @@
+<p>
+Default bar sparkline <img src="bar_spark.png" /> and another version of 
+the same <img src="bar_spark_s5.png" /> with the step set to 5.
+</p>
+<p>
+Bar sparkline <img src="bar_spark_bg.png" /> with an offwhite background
+color and another version of the same <img src="bar_spark_bg_s5.png" /> with
+ the step set to 5 and the minMarker turned off.
+</p>
+
diff --git a/examples/dataurl.hs b/examples/dataurl.hs
new file mode 100644
--- /dev/null
+++ b/examples/dataurl.hs
@@ -0,0 +1,12 @@
+
+import Graphics.Rendering.HSparklines
+
+dp :: [Float]
+dp = [24,21,32.3,24,15,34,43,55,57,72,74,75,73,72,55,44]
+
+main :: IO ()
+main = do
+  im <- make (barSpark {minMarker = False, maxMarker = False}) dp
+  gi <- encodePngAsDataUrl im
+  writeFile "dataurl.html" ("<p>This sparkline <img src=\"data:image/png;base64,"
+                            ++ gi ++ "\" /> is done inline.</p>")
diff --git a/examples/smooth.hs b/examples/smooth.hs
new file mode 100644
--- /dev/null
+++ b/examples/smooth.hs
@@ -0,0 +1,14 @@
+
+import Graphics.Rendering.HSparklines
+
+dp :: [Float]
+dp = [24,21,32.3,24,15,34,43,55,57,72,74,75,73,72,55,44]
+
+main :: IO ()
+main = do
+  make (smoothSpark) dp >>= savePngFile "smooth_spark.png"
+  make (smoothSpark {step = 5}) dp >>= savePngFile "smooth_spark_s5.png"
+  make (smoothSpark {bgColor = rgb 0xee 0xee 0xee}) dp >>=
+    savePngFile "smooth_spark_bg.png"
+  make (smoothSpark {bgColor = rgb 0xee 0xee 0xee, step = 5, minMarker = False}) dp
+    >>= savePngFile "smooth_spark_bg_s5.png"
diff --git a/examples/smooth.html b/examples/smooth.html
new file mode 100644
--- /dev/null
+++ b/examples/smooth.html
@@ -0,0 +1,10 @@
+<p>
+Default smooth sparkline <img src="smooth_spark.png" /> and another version of 
+the same <img src="smooth_spark_s5.png" /> with the step set to 5.
+</p>
+<p>
+Smooth sparkline <img src="smooth_spark_bg.png" /> with an offwhite background
+color and another version of the same <img src="smooth_spark_bg_s5.png" /> with
+ the step set to 5 and the minMarker turned off.
+</p>
+
diff --git a/hsparklines.cabal b/hsparklines.cabal
new file mode 100644
--- /dev/null
+++ b/hsparklines.cabal
@@ -0,0 +1,21 @@
+name:                hsparklines
+version:             0.1.0
+description:         Sparklines implementation of smooth and bar graphs
+synopsis:            Sparklines for Haskell
+license:             BSD3
+license-file:        LICENSE
+homepage:            http://www.jasani.org/search/label/hsparklines
+author:              Hitesh Jasani
+category:            Graphics
+maintainer:          <hitesh.jasani@gmail.com>
+Cabal-Version:       >= 1.2
+Build-Type:          Simple
+Tested-With:         GHC == 6.8.2
+extra-source-files:  README examples/bar.hs examples/bar.html examples/dataurl.hs
+                     examples/Makefile examples/smooth.hs examples/smooth.html
+
+library
+  build-depends:     base >= 3, bytestring, gd, dataenc
+  exposed-modules:   Graphics.Rendering.HSparklines
+  ghc-options:       -Wall
+
