diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) Erik Charlebois.
+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. The names of the author may not be used to endorse or promote
+   products derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS 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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+import Distribution.Simple
+import System.Cmd(system)
+
+main = defaultMainWithHooks $ simpleUserHooks { runTests = runElfTests }
+
+runElfTests a b pd lb = system "runhaskell -i./src ./tests/Test.hs" >> return ()
diff --git a/interpolatedstring-qq.cabal b/interpolatedstring-qq.cabal
new file mode 100644
--- /dev/null
+++ b/interpolatedstring-qq.cabal
@@ -0,0 +1,21 @@
+Name:          interpolatedstring-qq
+Version:       0.1
+License:       BSD3
+License-file:  LICENSE
+Category:      Data
+Author:        Erik Charlebois
+Copyright:     Erik Charlebois
+Maintainer:    Erik Charlebois <erikcharlebois@gmail.com>
+Stability:     unstable
+Cabal-Version: >= 1.2
+Build-Depends: base
+Build-Type:    Custom
+Synopsis:      QuasiQuoter for Ruby-style multi-line interpolated strings.
+Description:   QuasiQuoter for Ruby-style multi-line interpolated strings.
+Data-Files:    tests/Test.hs
+
+library
+    extensions:      TemplateHaskell
+    build-depends:   base, template-haskell, haskell-src-meta
+    hs-source-dirs:  src
+    exposed-modules: Text.InterpolatedString.QQ
diff --git a/src/Text/InterpolatedString/QQ.hs b/src/Text/InterpolatedString/QQ.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/InterpolatedString/QQ.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+-- | QuasiQuoter for interpolated strings using Ruby syntax. Expressions inside #{} will have
+-- 'show' called. Multi-line strings are supported. Escaping of '#' and '{' is done with backslash.
+--
+-- @
+-- v :: String
+-- v = [$istr| well \#{\"hello\" ++ \" there\"} \#{6*7}]
+-- @
+--
+-- v will have the value \" well hello there 42\"
+module Text.InterpolatedString.QQ (istr) where
+
+import qualified Language.Haskell.TH as TH
+import Language.Haskell.TH.Quote
+import Language.Haskell.Meta.Parse
+
+data StringPart = Literal String | AntiQuote String deriving Show
+
+parseHaskell a []          = [Literal (reverse a)]
+parseHaskell a ('\\':x:xs) = parseHaskell (x:a) xs
+parseHaskell a ('\\':[])   = parseHaskell ('\\':a) []
+parseHaskell a ('}':xs)    = AntiQuote (reverse a) : parseStr [] xs
+parseHaskell a (x:xs)      = parseHaskell (x:a) xs
+
+parseStr a []           = [Literal (reverse a)]
+parseStr a ('\\':x:xs)  = parseStr (x:a) xs
+parseStr a ('\\':[])    = parseStr ('\\':a) []
+parseStr a ('#':'{':xs) = Literal (reverse a) : parseHaskell [] xs
+parseStr a (x:xs)       = parseStr (x:a) xs
+
+makeExpr [] = [| "" |]
+makeExpr ((Literal a):xs)   = TH.appE [| (++) a |] (makeExpr xs)
+makeExpr ((AntiQuote a):xs) = TH.appE [| (++) (trimQuotes (show $(reifyStringToHaskell a))) |] (makeExpr xs)
+
+trimQuotes s = reverse $ dropWhile (== '"') $ reverse $ dropWhile (== '"') s
+
+reifyStringToHaskell s = 
+    case parseExp s of
+        Left s  -> TH.report True s >> [| "" |]
+        Right e ->  return e
+
+rstrExp s = makeExpr $ parseStr [] $ filter (/= '\r') s
+
+-- | QuasiQuoter for interpolating Haskell values into a string literal. The pattern portion is undefined.
+istr :: QuasiQuoter
+istr = QuasiQuoter rstrExp undefined
+
diff --git a/tests/Test.hs b/tests/Test.hs
new file mode 100644
--- /dev/null
+++ b/tests/Test.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Main where
+
+import Text.InterpolatedString.QQ
+import Test.HUnit
+
+data Foo = Foo Int String deriving Show
+
+t1 = "value"
+
+testEmpty = assertBool "" ([$istr||] == "")
+testNumLiteral = assertBool "" ([$istr|#{3}|] == "3")
+testString     = assertBool "" ([$istr|a string #{t1} is here|] == "a string value is here")
+testEscape     = assertBool "" ([$istr|#\{}|] == "#{}" && [$istr|\#{}|] == "#{}")
+testComplex    = assertBool "" ([$istr|
+        ok
+#{Foo 4 "Great!" : [Foo 3 "Scott!"]}
+        then
+|] == ("\n" ++
+    "        ok\n" ++
+    "[Foo 4 \"Great!\",Foo 3 \"Scott!\"]\n" ++
+    "        then\n"))
+
+
+tests = TestList
+    [ TestLabel "Empty String" $ TestCase testEmpty
+    , TestLabel "Number Literal" $ TestCase testNumLiteral
+    , TestLabel "String Variable" $ TestCase testString
+    , TestLabel "Escape Sequences" $ TestCase testEscape
+    , TestLabel "Complex Expression" $ TestCase testComplex
+    ]
+
+main = runTestTT tests
+
