diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+
+> import Distribution.Simple
+> main = defaultMain
diff --git a/Text/Ascetic.hs b/Text/Ascetic.hs
new file mode 100644
--- /dev/null
+++ b/Text/Ascetic.hs
@@ -0,0 +1,75 @@
+----------------------------------------------------------------
+--
+-- Ascetic
+-- 
+-- Text/Ascetic.hs
+--   Data structure, combinators, and functions for assembling
+--   data and emitting files in any XML-like or HTML-like
+--   markup language (consisting of tags, elements, attributes,
+--   declarations, and ASCII text content). Trade-offs are made
+--   in favor of simplicity and concision of constructors and
+--   combinators.
+
+----------------------------------------------------------------
+-- 
+
+module Text.Ascetic
+  where
+  
+import Data.String.Utils
+
+----------------------------------------------------------------
+-- Data type for simple markup trees and class for data types
+-- that can be converted into it.
+
+type Content = String
+type Tag = String
+type Attribute = String
+type Value = String
+
+data Ascetic =
+    C Tag Content                        -- Content.
+  | E Tag [Ascetic]                      -- Element.
+  | A Tag [(Attribute, Value)] [Ascetic] -- Element with attributes.
+  | D Tag [(Attribute, Value)] Ascetic   -- Declaration.
+  deriving  (Eq)
+
+class ToAscetic a where
+  ascetic :: a -> Ascetic
+
+----------------------------------------------------------------
+-- Conversion to ASCII string.
+
+instance Show Ascetic where
+  show x = to "" x where 
+    to ind x = case x of
+      C t c  -> ind ++ "<" ++ t ++ ">" ++ c ++ "</" ++ t ++ ">"
+      E t [] -> "<" ++ t ++ "/>"
+      E t xs -> 
+        ind 
+        ++ "<" ++ t ++ ">\n" 
+        ++ join "\n" [to (ind ++ "  ") x | x <- xs] 
+        ++ "\n" ++ ind ++ "</" ++ t ++ ">"
+      A t avs [] ->
+        ind 
+        ++ "<" ++ t ++ " " 
+               ++ join " " [a ++ "=\"" ++ v ++ "\"" | (a,v) <- avs] 
+        ++ "/>" 
+      A t avs xs ->
+        ind 
+        ++ "<" ++ t ++ " " 
+               ++ join " " [a ++ "=\"" ++ v ++ "\"" | (a,v) <- avs] 
+        ++ ">\n" 
+        ++ join "\n" [to (ind ++ "  ") x | x <- xs] 
+        ++ "\n" ++ ind ++ "</" ++ t ++ ">"
+      D t avs x ->
+        ind 
+        ++ "<?" ++ t ++ " " 
+                ++ join " " [a ++ "=\"" ++ v ++ "\"" | (a,v) <- avs] 
+        ++ "?>\n" 
+        ++ (to ind x)
+
+----------------------------------------------------------------
+-- Other useful functions.
+
+--eof
diff --git a/Text/Ascetic/HTML.hs b/Text/Ascetic/HTML.hs
new file mode 100644
--- /dev/null
+++ b/Text/Ascetic/HTML.hs
@@ -0,0 +1,73 @@
+----------------------------------------------------------------
+--
+-- Ascetic
+-- 
+-- Text/Ascetic/HTML.hs
+--   Wrappers for building HTML file represented using the
+--   Ascetic data structure.
+
+----------------------------------------------------------------
+-- 
+
+module Text.Ascetic.HTML
+  where
+
+import Data.String.Utils (join)
+
+import qualified Text.Ascetic as A
+
+----------------------------------------------------------------
+-- Data structures specific to HTML files.
+
+type Class = String
+type Selector = String
+type PseudoClass = Maybe String
+type Property = String
+type Value = String
+type DeclarationBlock = [(Property, Value)]
+data CSS = CSS [([Selector], PseudoClass, DeclarationBlock)]
+
+type HTML = A.Ascetic
+
+class ToHTML a where
+  html :: a -> HTML
+
+----------------------------------------------------------------
+-- Combinators for assembling HTML files.
+
+file :: HTML -> HTML -> HTML
+file head body = A.E "html" [head, body]
+
+head :: [HTML] -> HTML
+head hs = A.E "head" hs
+
+style :: CSS -> HTML
+style (CSS dbs) = 
+  A.C "style" $ "\n" ++ join "\n\n"
+    [ (join ", " ss) ++ " {\n  " 
+        ++ join "\n  " [p ++ ": " ++ v ++ ";" | (p,v) <- pvs] 
+        ++ "\n}" 
+    | (ss, pc, pvs) <- dbs] ++ "\n"
+
+script :: String -> HTML
+script hs = A.C "script" ""
+
+body :: [HTML] -> HTML
+body hs = A.E "body" hs
+
+div :: [HTML] -> HTML
+div hs = A.E "div" hs
+
+divWith :: [(A.Attribute, A.Value)] -> [HTML] -> HTML
+divWith avs hs = A.A "div" avs hs
+
+span :: [HTML] -> HTML
+span hs = A.E "span" hs
+
+content :: String -> HTML
+content s = A.C "span" s
+
+----------------------------------------------------------------
+-- Other useful functions.
+
+--eof
diff --git a/ascetic.cabal b/ascetic.cabal
new file mode 100644
--- /dev/null
+++ b/ascetic.cabal
@@ -0,0 +1,14 @@
+Name:              ascetic
+Version:           0.0.0.1
+Synopsis:          Generic markup builder.
+Description:       Module for assembling/emitting files in any XML-like language.
+Category:          Text
+License:           GPL
+Author:            Andrei Lapets
+Maintainer:        Andrei Lapets <lapets@bu.edu>
+Build-Type:        Simple
+Cabal-Version:     >= 1.2
+
+library
+  exposed-modules: Text.Ascetic, Text.Ascetic.HTML
+  build-depends:   base >= 3 && < 5, MissingH
