diff --git a/Data/String/Interpolation.hs b/Data/String/Interpolation.hs
new file mode 100644
--- /dev/null
+++ b/Data/String/Interpolation.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE QuasiQuotes,TemplateHaskell,DeriveDataTypeable #-}
+module Data.String.Interpolation(str) where
+import Language.Haskell.TH as TH
+import Language.Haskell.TH.Quote
+import Data.Data
+import Data.Maybe
+import Data.Char
+import Data.List(intercalate)
+
+quoteExprExp :: String -> TH.ExpQ
+-- | Quasiquote 'str' implements multiline strings with interpolation.
+--   Interpolating a value of parameter a into the string is done by $a$
+--   and interpolating anything with instance Show is $:a$.
+--
+--   Repetitive patterns can be made by # symbol using the following syntax: 
+--
+--  @
+--  \#\<var\> in \<list\>: \<interpolated string\> (|\<interpolated string\>)\#
+--  @
+--   
+--   Where (|\<interpolated string\>) denotes optional separator for the 
+--   elements.
+--   
+--
+--   Example:
+-- 
+--   @
+--    \#i in myList: this is $i$|--\#
+--   @
+--   
+--   Which will evaluate to @ 1--2--3 @ given myList of [1,2,3]
+--   
+-- 
+--   Multiline indentation is handled by aligning on smallest un-empty
+--   line after the first.
+--
+--   Pattern matching is not supported. 
+--
+
+str  :: QuasiQuoter
+str  =  QuasiQuoter quoteExprExp undefined
+--
+quoteExprExp s = psToStringE (parParse $ norming s)
+--
+
+psToStringE :: PieceString -> TH.Q TH.Exp
+psToStringE [] = TH.stringE ""
+psToStringE (x:xs) = TH.infixE (Just $ sbitToExp x)
+                               ([| (++) |])
+                               (Just $ psToStringE xs)
+
+sbitToExp :: StringBits -> ExpQ
+sbitToExp (Str x) =  TH.stringE x 
+sbitToExp (Var x)  =  (TH.varE (TH.mkName x))
+sbitToExp (SVar x) = TH.appE (TH.varE (TH.mkName "show"))
+                        (TH.varE (TH.mkName x))
+
+sbitToExp (RepVar varName lstName rep sep) 
+    = [|intercalate $(sepr) (map $(lam) $(lstN))|]
+    where
+     sepr = psToStringE (fromMaybe [Str ""] sep)
+     lam  = TH.lamE [varN] (psToStringE rep)
+     varN = TH.varP $ TH.mkName varName
+     lstN = TH.varE $ TH.mkName lstName
+
+type PieceString = [StringBits]
+data StringBits = Str String | Var String | SVar String
+                  | RepVar String String 
+                    PieceString (Maybe PieceString)
+                deriving (Eq,Ord,Show,Typeable,Data)
+
+-- Split to string into pieces. This needs proper error messages.
+-- Perhaps parsec?
+parParse :: [Char] -> [StringBits]
+parParse [] = []
+
+parParse ('$':'$':s) = Str "$":parParse s -- Parse escapes
+parParse ('#':'#':s) = Str "#":parParse s
+
+parParse ('$':':':s) = SVar (takeWhile (/='$') s) -- Parse antiquotes
+                        :parParse (drop 1 (dropWhile (/='$') s))
+parParse ('$':s) = Var (takeWhile (/='$') s)
+                    :parParse (drop 1 (dropWhile (/='$') s))
+
+parParse ('#':s) = let (bind,exprS) = break (==':') s
+                       (hasSep,expr,sepS) = takeRep $ drop 1 exprS
+                       (sep,restS) = break (=='#') $ sepS
+                       rest = drop 1 restS
+                       [varName,"in",listName] = words bind
+                    in if hasSep 
+                        then RepVar varName listName 
+                             (parParse expr) (Just $ parParse sep) 
+                             : parParse rest
+                        else RepVar varName listName 
+                             (parParse expr) (Nothing) 
+                             : parParse sepS
+
+parParse s = Str (takeWhile (notIn "$#") s)
+                 : parParse (dropWhile (notIn "$#") s) 
+
+notIn :: (Eq a) => [a] -> a -> Bool
+notIn s x =not $ elem x s 
+
+takeRep :: String -> (Bool,String,String)
+takeRep x = takeRep' x []
+
+takeRep' :: String -> String -> (Bool,String,String)
+takeRep' [] _ = error "Repetition template does not end"
+takeRep' ('|':'|':s) acc = takeRep' s ('|':acc)
+takeRep' ('|':s) acc = (True,reverse acc,s)
+takeRep' ('#':s) acc = (False,reverse acc,s)
+takeRep' (r:s) acc = takeRep' s (r:acc)
+
+
+-- Normalize the indentation to match second line
+
+norming :: String -> String
+norming = unlines . norming' . lines
+
+norming':: [String] -> [String]
+norming' [] = []
+norming' (l:lst) = l:map (drop (n)) lst
+    where 
+     n = minimumD 0 $ map (length . takeWhile (==' ') ) 
+         $ (filter (not.isEmpty) lst)
+     isEmpty = all (isSpace)
+
+
+minimumD :: (Ord a) => a -> [a] -> a
+minimumD d [] = d
+minimumD _ x  = minimum x
+
diff --git a/Interpolation.cabal b/Interpolation.cabal
new file mode 100644
--- /dev/null
+++ b/Interpolation.cabal
@@ -0,0 +1,18 @@
+Name:                  Interpolation
+Version:             0.1
+Description:         This package adds quasiquoter for multiline 
+                     strings, interpolation and simple templating.
+                     Handy for text generation.
+Category:            Text
+Synopsis:            Multiline strings, interpolation and templating.
+License:             OtherLicense
+License-file:        LICENSE
+Author:              Ville Tirronen
+Maintainer:          aleator@gmail.com
+Build-Type:          Simple
+Cabal-Version:       >=1.2
+
+Library
+  Build-Depends:     base, syb, template-haskell
+  Exposed-modules:   Data.String.Interpolation
+  ghc-options:       -Wall 
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+
+
+The MIT License
+
+Copyright (c) 2009 Ville Tirronen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
