diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,18 @@
+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,4 @@
+import Distribution.Simple
+
+main = defaultMain
+
diff --git a/nicify-lib.cabal b/nicify-lib.cabal
new file mode 100644
--- /dev/null
+++ b/nicify-lib.cabal
@@ -0,0 +1,25 @@
+Name:           nicify-lib
+Version:        1.0
+Synopsis:       Pretty print the standard output of show for algebraic datatypes
+Description:    Pretty print the standard output of show for algebraic datatypes
+                
+License:        MIT
+License-File:   LICENSE
+Author:         Julian Fleischer
+Maintainer:     julian@scravy.de
+Build-Type:     Simple
+Cabal-Version:  >= 1.8
+Category:       Text, Tools, Utilities
+Stability:      stable
+
+Source-Repository head
+    type: git
+    location: https://github.com/scravy/nicify-lib
+
+Library
+    Exposed-Modules:    Text.Nicify
+    Build-Depends:      base >= 4 && < 5
+                        , parsec >= 3
+                        , transformers >= 0.3
+    Hs-Source-Dirs:     src
+
diff --git a/src/Text/Nicify.hs b/src/Text/Nicify.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Nicify.hs
@@ -0,0 +1,102 @@
+{-# LANGUAGE Haskell2010
+    , DeriveDataTypeable
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-unused-do-bind
+    -fno-warn-name-shadowing
+ #-}
+
+module Text.Nicify (
+    nicify,
+    X (..),
+    parseX,
+    printX,
+    printX'
+  ) where
+
+
+import Data.Data
+import Data.Functor.Identity
+import Text.Parsec
+
+
+data X = XString String
+       | XCurly [X]
+       | XBrackets [X]
+       | XAnything String
+       | XSep
+    deriving (Show, Read, Eq, Data, Typeable)
+
+
+nicify :: String -> String
+nicify = printX . parseX
+
+type Parser a = ParsecT String () Identity a
+
+parseX :: String -> [X]
+parseX = either (const []) id . runParser (many rData) () "-"
+
+printX :: [X] -> String
+printX = printX' ""
+
+printX' :: String -> [X] -> String
+printX' indent = (indent ++) . concatMap (prettify indent)
+
+prettify :: String -> X -> String
+prettify indent x = case x of
+    XAnything s -> s
+    XString s -> '\"' : foldr stringify "\"" s
+    XSep -> ",\n" ++ indent
+    XCurly [] -> "{}"
+    XBrackets [] -> "[]"
+    XCurly x -> "{\n" ++ indent' ++ foldr (++) ('\n' : indent ++ "}") (map (prettify indent') x)
+    XBrackets x -> "[\n" ++ indent' ++ foldr (++) ('\n' : indent ++ "]") (map (prettify indent') x)
+  where
+    indent' = indent ++ "    "
+    stringify c cs = case c of
+        '\"' -> "\\\"" ++ cs
+        '\\' -> "\\\\" ++ cs
+        char -> char : cs
+
+rData, rSep, rAnything, rCurly, rBrackets, rString :: Parser X
+
+rData = rString <|> rCurly <|> rBrackets <|> rSep <|> rAnything
+
+rSep = do
+    char ','
+    spaces
+    return XSep
+
+rAnything = do
+    str <- many1 (noneOf "\"{}[],")
+    return $ XAnything str
+
+rCurly = do
+    char '{'
+    str <- many rData
+    char '}'
+    return $ XCurly str
+
+rBrackets = do
+    char '['
+    str <- many rData
+    char ']'
+    return $ XBrackets str
+
+rString = do
+    char '\"'
+    str <- many (noneOf "\\\"" <|> escape)
+    char '\"'
+    return $ XString str
+
+escape :: Parser Char
+escape = do
+    char '\\'
+    c <- anyChar
+    case c of
+        'n' -> return '\n'
+        'r' -> return '\r'
+        't' -> return '\t'
+        any -> return any
+
