diff --git a/5.txt b/5.txt
new file mode 100644
--- /dev/null
+++ b/5.txt
@@ -0,0 +1,336 @@
+   NAME SYNOPSIS DESCRIPTION TAG TYPES COPYRIGHT SEE ALSO
+
+                                 1. mustache(5)
+                                                           2. Mustache Manual
+                                                               3. mustache(5)
+
+NAME
+
+   mustache - Logic-less templates.
+
+SYNOPSIS
+
+   A typical Mustache template:
+
+ Hello {{name}}
+ You have just won {{value}} dollars!
+ {{#in_ca}}
+ Well, {{taxed_value}} dollars, after taxes.
+ {{/in_ca}}
+
+   Given the following hash:
+
+ {
+   "name": "Chris",
+   "value": 10000,
+   "taxed_value": 10000 - (10000 * 0.4),
+   "in_ca": true
+ }
+
+   Will produce the following:
+
+ Hello Chris
+ You have just won 10000 dollars!
+ Well, 6000.0 dollars, after taxes.
+
+DESCRIPTION
+
+   Mustache can be used  for HTML, config files,  source code - anything.  It
+   works by expanding tags in a template  using values provided in a hash  or
+   object.
+
+   We call it "logic-less" because there are no if statements, else  clauses,
+   or for loops. Instead there are only  tags. Some tags are replaced with  a
+   value, some nothing, and others a series of values. This document explains
+   the different types of Mustache tags.
+
+TAG TYPES
+
+   Tags are indicated  by the double  mustaches. {{person}} is  a tag, as  is
+   {{#person}}. In both examples, we'd refer to person as the key or tag key.
+   Let's talk about the different types of tags.
+
+  Variables
+
+   The most  basic tag  type  is the  variable. A  {{name}}  tag in  a  basic
+   template will try to find the name key in the current context. If there is
+   no name key, the parent contexts  will be checked recursively. If the  top
+   context is reached and the  name key is still  not found, nothing will  be
+   rendered.
+
+   All variables are HTML escaped by default. If you want to return unescaped
+   HTML, use the triple mustache: {{{name}}}.
+
+   You can also use & to unescape a variable: {{& name}}. This may be  useful
+   when changing delimiters (see "Set Delimiter" below).
+
+   By default a variable "miss" returns an empty string. This can usually  be
+   configured in your Mustache library. The Ruby version of Mustache supports
+   raising an exception in this situation, for instance.
+
+   Template:
+
+ * {{name}}
+ * {{age}}
+ * {{company}}
+ * {{{company}}}
+
+   Hash:
+
+ {
+   "name": "Chris",
+   "company": "<b>GitHub</b>"
+ }
+
+   Output:
+
+ * Chris
+ *
+ * &lt;b&gt;GitHub&lt;/b&gt;
+ * <b>GitHub</b>
+
+  Sections
+
+   Sections render blocks of text one  or more times, depending on the  value
+   of the key in the current context.
+
+   A section begins with a pound and ends with a slash. That is,  {{#person}}
+   begins a "person" section while {{/person}} ends it.
+
+   The behavior of the section is determined by the value of the key.
+
+   False Values or Empty Lists
+
+   If the person key exists  and has a value of  false or an empty list,  the
+   HTML between the pound and slash will not be displayed.
+
+   Template:
+
+ Shown.
+ {{#person}}
+   Never shown!
+ {{/person}}
+
+   Hash:
+
+ {
+   "person": false
+ }
+
+   Output:
+
+ Shown.
+
+   Non-Empty Lists
+
+   If the person key exists and has  a non-false value, the HTML between  the
+   pound and slash will be rendered and displayed one or more times.
+
+   When the  value  is a  non-empty  list, the  text  in the  block  will  be
+   displayed once for each item in the list. The context of the block will be
+   set to the current item for each  iteration. In this way we can loop  over
+   collections.
+
+   Template:
+
+ {{#repo}}
+   <b>{{name}}</b>
+ {{/repo}}
+
+   Hash:
+
+ {
+   "repo": [
+     { "name": "resque" },
+     { "name": "hub" },
+     { "name": "rip" }
+   ]
+ }
+
+   Output:
+
+ <b>resque</b>
+ <b>hub</b>
+ <b>rip</b>
+
+   Lambdas
+
+   When the value is  a callable object,  such as a  function or lambda,  the
+   object will be invoked and  passed the block of  text. The text passed  is
+   the literal block, unrendered. {{tags}} will not have been expanded -  the
+   lambda should do that on its own. In this way you can implement filters or
+   caching.
+
+   Template:
+
+ {{#wrapped}}
+   {{name}} is awesome.
+ {{/wrapped}}
+
+   Hash:
+
+ {
+   "name": "Willy",
+   "wrapped": function() {
+     return function(text, render) {
+       return "<b>" + render(text) + "</b>"
+     }
+   }
+ }
+
+   Output:
+
+ <b>Willy is awesome.</b>
+
+   Non-False Values
+
+   When the value is non-false but not a list, it will be used as the context
+   for a single rendering of the block.
+
+   Template:
+
+ {{#person?}}
+   Hi {{name}}!
+ {{/person?}}
+
+   Hash:
+
+ {
+   "person?": { "name": "Jon" }
+ }
+
+   Output:
+
+ Hi Jon!
+
+  Inverted Sections
+
+   An inverted section begins with a caret (hat) and ends with a slash.  That
+   is {{^person}} begins a "person"  inverted section while {{/person}}  ends
+   it.
+
+   While sections can be used to render  text one or more times based on  the
+   value of the  key, inverted  sections may render  text once  based on  the
+   inverse value  of the  key. That  is, they  will be  rendered if  the  key
+   doesn't exist, is false, or is an empty list.
+
+   Template:
+
+ {{#repo}}
+   <b>{{name}}</b>
+ {{/repo}}
+ {{^repo}}
+   No repos :(
+ {{/repo}}
+
+   Hash:
+
+ {
+   "repo": []
+ }
+
+   Output:
+
+ No repos :(
+
+  Comments
+
+   Comments begin with a bang and are ignored. The following template:
+
+ <h1>Today{{! ignore me }}.</h1>
+
+   Will render as follows:
+
+ <h1>Today.</h1>
+
+   Comments may contain newlines.
+
+  Partials
+
+   Partials begin with a greater than sign, like {{> box}}.
+
+   Partials are  rendered  at  runtime  (as  opposed  to  compile  time),  so
+   recursive partials are possible. Just avoid infinite loops.
+
+   They   also    inherit    the    calling   context.    Whereas    in    an
+   [ERB](http://en.wikipedia.org/wiki/ERuby) file you may have this:
+
+ <%= partial :next_more, :start => start, :size => size %>
+
+   Mustache requires only this:
+
+ {{> next_more}}
+
+   Why? Because the next_more.mustache file  will inherit the size and  start
+   methods from the calling context.
+
+   In this way you  may want to  think of partials  as includes, or  template
+   expansion, even though it's not literally true.
+
+   For example, this template and partial:
+
+ base.mustache:
+ <h2>Names</h2>
+ {{#names}}
+   {{> user}}
+ {{/names}}
+
+ user.mustache:
+ <strong>{{name}}</strong>
+
+   Can be thought of as a single, expanded template:
+
+ <h2>Names</h2>
+ {{#names}}
+   <strong>{{name}}</strong>
+ {{/names}}
+
+  Set Delimiter
+
+   Set Delimiter tags start with an equal sign and change the tag  delimiters
+   from {{ and }} to custom strings.
+
+   Consider the following contrived example:
+
+ * {{default_tags}}
+ {{=<% %>=}}
+ * <% erb_style_tags %>
+ <%={{ }}=%>
+ * {{ default_tags_again }}
+
+   Here we have a list with three items. The first item uses the default  tag
+   style, the second uses erb style as defined by the Set Delimiter tag,  and
+   the third returns  to the default  style after yet  another Set  Delimiter
+   declaration.
+
+   According to ctemplates,  this "is  useful for languages  like TeX,  where
+   double-braces may occur in the text and are awkward to use for markup."
+
+   Custom delimiters may not contain whitespace or the equals sign.
+
+COPYRIGHT
+
+   Mustache is Copyright (C) 2009 Chris Wanstrath
+
+   Original CTemplate by Google
+
+SEE ALSO
+
+   mustache(1), http://mustache.github.io/
+
+                                   1. DEFUNKT
+                                                                2. April 2014
+                                                               3. mustache(5)
+
+References
+
+   Visible links
+   . http://mustache.github.io/mustache.5.html#NAME
+   . http://mustache.github.io/mustache.5.html#SYNOPSIS
+   . http://mustache.github.io/mustache.5.html#DESCRIPTION
+   . http://mustache.github.io/mustache.5.html#TAG-TYPES
+   . http://mustache.github.io/mustache.5.html#COPYRIGHT
+   . http://mustache.github.io/mustache.5.html#SEE-ALSO
+   . http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html
+   . http://mustache.github.io/mustache.1.ron.html
+   . http://mustache.github.io/
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Daniel Choi
+
+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/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,43 @@
+module Main where
+import Text.Mustache
+import qualified Text.Show.Pretty as Pr
+import System.Environment
+import Data.Aeson
+import qualified Data.Text.Lazy.IO as TL
+import qualified Data.ByteString.Lazy.Char8 as BL
+import qualified Data.Text.Lazy.IO as TL
+import qualified Data.Text.Lazy.Builder as B
+import Data.Maybe
+import qualified Text.Show.Pretty as Pr
+import Options.Applicative
+
+data Options = Options Bool FilePath deriving (Show)
+
+parseOpts :: Parser Options
+parseOpts = Options 
+    <$> (flag False True (short 'c' <> help "Just output parse tree of template file"))
+    <*> (argument str (metavar "FILE"))
+
+opts = info 
+          (helper <*> parseOpts)
+          (fullDesc 
+            <> progDesc "A Haskell implementation of Mustache templates.\nOn STDIN provide the JSON to insert into the template."
+            <> header "mus v0.1.0.0")
+
+main = do
+    opts' <- execParser opts 
+    case opts' of
+      Options True file -> do
+        s <- readFile file
+        xs <- readTemplate s
+        putStrLn $ Pr.ppShow xs
+      Options False file -> do
+        s <- readFile file
+        chunks <- readTemplate s
+        input <- BL.getContents
+        let value = fromJust $ decode input
+        let res = runTemplate chunks value
+        TL.putStrLn . B.toLazyText $ res
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,67 @@
+# mustache-haskell
+
+A Haskell implementation of mustache templates.
+
+Should be compatible with the the [mustache
+specification](http://mustache.github.io/mustache.5.html).
+
+
+## Install
+
+You need the Haskell platform on your system.
+
+```
+cabal install mustache
+```
+
+Or alternatively
+
+``` 
+git clone git@github.com:danchoi/mustache-haskell.git
+cd mustache-haskell
+cabal sandbox init
+cabal install
+# Now copy .cabal-sandbox/bin/mus to your PATH
+```
+
+## Usage
+
+```
+mus template.mustache < input.json
+```
+
+```
+mus v0.1.0.0
+
+Usage: mus [-c] FILE
+  A Haskell implementation of Mustache templates. On STDIN provide the JSON to
+  insert into the template.
+
+Available options:
+  -h,--help                Show this help text
+  -c                       Just output parse tree of template file
+```
+
+## List separator syntax
+
+mustache-haskell adds one additional feature to the mustache specification.  If
+you are outputing elements of a list, you can designate an optional list
+separator with the following syntax:
+
+
+```
+{{#hobbies, }}{{#name}}{{/hobbies}}
+```
+
+This designates `", "` as the list separator and will output
+
+```
+sewing, brewing, cooking
+```
+
+when the input is 
+
+```json
+{"hobbies":[{"name":"sewing"},{"name":"brewing"},{"name":"cooking"}]}
+```
+
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
diff --git a/Text/Mustache.hs b/Text/Mustache.hs
new file mode 100644
--- /dev/null
+++ b/Text/Mustache.hs
@@ -0,0 +1,103 @@
+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
+module Text.Mustache (
+  runTemplate
+, module Text.Mustache.Parse
+) where
+import Text.Mustache.Types
+import Text.Mustache.Parse
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Lazy.IO as TL
+import qualified Data.Text.Lazy.Builder as B
+import qualified Data.Text.Lazy.Builder.Int as B
+import qualified Data.Text.Lazy.Builder.RealFloat as B
+import Data.List (intersperse)
+import Data.Monoid
+import Data.Aeson
+import qualified Data.HashMap.Lazy as HM
+import qualified Data.Vector as V
+import Data.Scientific 
+
+------------------------------------------------------------------------ 
+-- | Evaluation functions
+
+runTemplate :: [Chunk] -> Value -> B.Builder
+runTemplate xs v = mconcat
+    $ map (chunkToBuilder v) xs
+
+chunkToBuilder :: Value -> Chunk -> B.Builder
+chunkToBuilder v (Var k) = evalToBuilder True k v
+chunkToBuilder v (UnescapedVar k) = evalToBuilder False k v  
+chunkToBuilder v (Comment _) = mempty
+chunkToBuilder v (SetDelimiter _ _) = mempty
+chunkToBuilder v (Plain x) = B.fromText x
+chunkToBuilder v (Section ks chunks sep) = 
+    case evalKeyPath ks v of 
+      Array v' -> 
+          let evalItem :: Value -> B.Builder
+              evalItem loopValue = mconcat $ map (chunkToBuilder $ mergeValues v loopValue) chunks
+          in mconcat $ intersperse (maybe mempty B.fromText sep) $ map evalItem $ V.toList v'
+      x@(Object _) -> mconcat $ map (chunkToBuilder $ mergeValues v x) chunks 
+      _ -> mempty
+chunkToBuilder v (InvertedSection ks chunks) = 
+    case evalKeyPath ks v of
+      Null -> chunkToBuilder v (Section (init ks) chunks Nothing)
+      Bool False -> chunkToBuilder v (Section (init ks) chunks Nothing)
+      _ -> mempty
+chunkToBuilder v (Partial s) = B.fromText $ "{{ERROR: include partial " <> T.pack s <> "}}"
+
+mergeValues :: Value -> Value -> Value
+mergeValues (Object outer) (Object inner) = Object $ HM.union inner outer
+mergeValues _ inner = inner
+
+evalToBuilder :: Bool -> KeyPath -> Value -> B.Builder
+evalToBuilder escape k v = valToBuilder escape $ evalKeyPath k v
+
+-- evaluates the a JS key path against a Value context to a leaf Value
+evalKeyPath :: KeyPath -> Value -> Value
+evalKeyPath [] x@(String _) = x
+evalKeyPath [] x@Null = x
+evalKeyPath [] x@(Number _) = x
+evalKeyPath [] x@(Bool _) = x
+evalKeyPath [] x@(Object _) = x
+evalKeyPath (Key ".":[]) x = x
+evalKeyPath [] x@(Array _) = x 
+evalKeyPath (Key key:ks) (Object s) = 
+    case (HM.lookup key s) of
+        Just x          -> evalKeyPath ks x
+        Nothing -> Null
+evalKeyPath (Index idx:ks) (Array v) = 
+      let e = (V.!?) v idx
+      in case e of 
+        Just e' -> evalKeyPath ks e'
+        Nothing -> Null
+evalKeyPath ((Index _):_) _ = Null
+evalKeyPath _ _ = Null
+
+valToBuilder :: Bool -> Value -> B.Builder
+valToBuilder True (String x) = B.fromText . htmlEscape $ x
+valToBuilder False (String x) = B.fromText x
+valToBuilder _ Null = B.fromText "null"
+valToBuilder _ (Bool True) = B.fromText "true"
+valToBuilder _ (Bool False) = B.fromText "false"
+valToBuilder _ (Number x) = 
+    case floatingOrInteger x of
+        Left float -> B.realFloat float
+        Right int -> B.decimal int
+valToBuilder _ (Object x) = B.fromText . T.pack . show $ x
+
+
+
+-- | Escape HTML symbols
+-- adapted from Hastache.hs -- thank you
+htmlEscape :: T.Text -> T.Text
+htmlEscape = T.concatMap proc
+  where
+    proc '&'  = "&amp;"
+    proc '\\' = "&#92;"
+    proc '"'  = "&quot;"
+    proc '\'' = "&#39;"
+    proc '<'  = "&lt;"
+    proc '>'  = "&gt;"
+    proc h    = T.singleton h
+
diff --git a/Text/Mustache/Parse.hs b/Text/Mustache/Parse.hs
new file mode 100644
--- /dev/null
+++ b/Text/Mustache/Parse.hs
@@ -0,0 +1,181 @@
+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
+module Text.Mustache.Parse (
+    runParse
+  , readTemplate
+) where
+import Text.Mustache.Types
+import Text.Parsec
+import Data.Functor.Identity
+import Control.Applicative hiding (many, (<|>))
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Monoid
+import System.Directory 
+
+-- Custom delimiters may not contain whitespace or the equals sign.
+type DelimiterState = (String, String)  -- left and right delimiters
+
+defDelimiters = ("{{", "}}")
+
+type Parser a = ParsecT String DelimiterState Identity a
+
+readTemplate :: String -> IO [Chunk]
+readTemplate = loadPartials . runParse 
+
+-- | preload partials
+
+loadPartials :: [Chunk] -> IO [Chunk]
+loadPartials xs = mapM loadPartial xs >>= return . concat
+
+loadPartial :: Chunk -> IO [Chunk]
+loadPartial (Partial path) = do
+      e <- doesFileExist path
+      if e 
+      then do
+        s <- readFile path
+        return $ runParse s 
+      else error $ "Partial file missing: " ++ path
+loadPartial (Section k cs sep) = do
+      cs' <- mapM loadPartial cs
+      return [Section k (concat cs') sep]
+loadPartial (InvertedSection k cs) = do
+      cs' <- mapM loadPartial cs
+      return [InvertedSection k (concat cs')]
+loadPartial x = return [x]
+
+
+runParse :: String -> [Chunk]
+runParse input = 
+    case (runParserT (many chunk) defDelimiters "" input) of
+        Identity (Left x) -> error $ "parser failed: " ++ show x
+        Identity (Right xs') -> xs'
+
+delimiters :: Monad m => ParsecT s DelimiterState m DelimiterState
+delimiters = getState 
+
+leftDelimiter :: Parser String
+leftDelimiter = do 
+    (x,_) <- delimiters 
+    string x <* spaces
+
+rightDelimiter = do
+    (_,x) <- delimiters 
+    string x 
+
+inDelimiters p = (between leftDelimiter (spaces >> rightDelimiter) p) <?> "inDelimiters"
+
+varname :: Parser String
+varname = (many1 (alphaNum <|> oneOf ".[]0-9_")) <?> "varname"
+
+chunk :: Parser Chunk
+chunk = choice [
+      try unescapedVar
+    , try var
+    , try section
+    , try invertedSection
+    , try setDelimiter
+    , try partial
+    , plain
+    ]
+
+var :: Parser Chunk 
+var = (Var <$> inDelimiters keyPath) <?> "var"
+
+unescapedVar = 
+  (UnescapedVar 
+    <$> (try tripleBraceForm <|> ampersandForm)) <?> "unescapedVar"
+  where tripleBraceForm = between (string "{{{" <* spaces)
+                                  (spaces *> string "}}}")
+                                  keyPath
+        ampersandForm = inDelimiters ((char '&' >> spaces) *> keyPath)
+
+-- {{#section}} is a section; optional separator may be designated as {{#section|,}}
+section :: Parser Chunk
+section = do
+    (key, sep) <- inDelimiters ((char '#' >> spaces) *> ((,) <$> keyPath <*> sep))
+    xs :: [Chunk] <- manyTill chunk (closeTag key)
+    (return  $ Section key xs sep) <?> ("section " ++ show key)
+
+sep :: Parser (Maybe Text)
+sep  = do
+  spaces 
+  Just <$> do
+    spaces
+    notFollowedBy rightDelimiter
+    x <- anyChar
+    xs <- manyTill anyChar ((eof >> (string "")) <|> bumpClose)
+    return . T.pack $ x:xs
+  <|> pure Nothing
+
+invertedSection :: Parser Chunk
+invertedSection = do
+    key <- inDelimiters ((char '^' >> spaces) *> keyPath)
+    xs :: [Chunk] <- manyTill chunk (closeTag key)
+    (return  $ InvertedSection key xs) <?> ("section " ++ show key)
+
+setDelimiter :: Parser Chunk
+setDelimiter = do
+  (left, right) <- inDelimiters $ do
+      char '='
+      left <- many1 (noneOf "= ")
+      spaces
+      right <- many1 (noneOf "= ")
+      char '='
+      return (left, right)
+  setState (left, right)
+  return $ SetDelimiter left right
+
+closeTag :: KeyPath -> Parser String
+closeTag k = try (inDelimiters (char '/' *> string k')) 
+  where k' = keyPathToString k
+
+partial = do
+  Partial <$> (inDelimiters ((char '>' >> spaces) *> filename))
+
+filename :: Parser String
+filename = (many1 (alphaNum <|> oneOf "/.[]0-9_")) <?> "filename"
+
+plain = do
+    -- thanks to http://stackoverflow.com/a/20735868/232417
+    notFollowedBy leftDelimiter
+    x <- anyChar
+    xs <- manyTill anyChar ((eof >> (string "")) <|> bumpOpen)
+    return . Plain . T.pack $ x:xs
+
+bumpOpen = (lookAhead $ try leftDelimiter) <?> "bumpOpen"
+bumpClose = (lookAhead $ try rightDelimiter) <?> "bumpClose"
+
+
+------------------------------------------------------------------------
+
+keyPath :: Parser KeyPath
+keyPath = do
+  raw <- varname
+  let res = parse (sepBy1 pKeyOrIndex (many1 $ oneOf ".[")) "" raw
+  spaces
+  return 
+    $ case res of 
+        Left err -> error $ "Can't parse keypath: " ++ raw
+        Right res' -> res'
+
+keyPathToString :: KeyPath -> String
+keyPathToString xs = go xs
+  where go ((Key x):[]) = T.unpack x 
+        go ((Key x):xs) = T.unpack x
+                  <> "."
+                  <> keyPathToString xs
+        go ((Index x):xs) = 
+              "[" <> (show x) 
+              <> (']':keyPathToString xs)
+        go [] = []
+
+pKeyOrIndex = pIndex <|> pKey
+
+pKey = Key . T.pack 
+    <$> (
+        ((:[]) <$> char '.')  -- immediate context key
+        <|> (many1 (alphaNum <|> noneOf ".[")) 
+        )
+
+pIndex = Index . read <$> (many1 digit) <* char ']'
+
diff --git a/Text/Mustache/Types.hs b/Text/Mustache/Types.hs
new file mode 100644
--- /dev/null
+++ b/Text/Mustache/Types.hs
@@ -0,0 +1,18 @@
+module Text.Mustache.Types
+where
+import Data.Text (Text)
+
+data Chunk = Var KeyPath  
+         | UnescapedVar KeyPath
+         | Section KeyPath [Chunk] (Maybe Text)  -- separator text
+         | InvertedSection KeyPath [Chunk]
+         | Comment KeyPath
+         | SetDelimiter String String -- a stateful operation
+         | Plain Text
+         | Partial FilePath
+         deriving (Show, Read, Eq)
+
+type KeyPath = [Key]
+data Key = Key Text | Index Int deriving (Eq, Show, Read)
+
+
diff --git a/mustache-haskell.cabal b/mustache-haskell.cabal
new file mode 100644
--- /dev/null
+++ b/mustache-haskell.cabal
@@ -0,0 +1,61 @@
+-- Initial text-mustache.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                mustache-haskell 
+version:             0.1.0.0
+synopsis:            straight implementation of mustache templates
+-- description:         
+homepage:            https://github.com/danchoi/mustache
+license:             MIT
+license-file:        LICENSE
+author:              Daniel Choi
+maintainer:          dhchoi@gmail.com
+-- copyright:           
+category:            Text
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+library 
+  default-language: Haskell2010
+  hs-source-dirs: .
+  exposed-modules:
+      Text.Mustache.Types
+      Text.Mustache
+  other-modules:
+      Text.Mustache.Parse
+  build-depends:       base >=4.7 && <4.8
+                     , aeson
+                     , text
+                     , parsec
+                     , transformers
+                     , pretty-show
+                     , aeson
+                     , unordered-containers
+                     , vector
+                     , scientific >=0.3.0.0 && <0.4.0.0
+                     , directory
+                     , bytestring
+
+
+executable mus
+  main-is:             Main.hs
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base >=4.7 && <4.8
+                     , aeson
+                     , text
+                     , mustache-haskell
+                     , parsec
+                     , directory
+                     , transformers
+                     , pretty-show
+                     , bytestring
+                     , aeson
+                     , unordered-containers
+                     , vector
+                     , scientific
+                     , directory
+                     , optparse-applicative >=0.11.0 && <0.12.0
+  default-language:    Haskell2010
+
diff --git a/test1.mustache b/test1.mustache
new file mode 100644
--- /dev/null
+++ b/test1.mustache
@@ -0,0 +1,23 @@
+ehllo {{test}}  {{{unesc}}}
+
+{{#section}}
+  hello
+  {{#name}} hello {{first}} {{/name}}
+{{/section}}
+
+{{^section2}}
+
+  inverted
+{{/section2}}
+
+{{=<% %>=}}
+
+{{notdelimited}}
+
+<% newdelim %>
+
+<%={{ }}=%>
+
+{{ old_delim }}
+
+<% invalid_delim %>
