diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,17 +1,18 @@
-## Madlibs DSL for generating random text
+# Madlang DSL for generating random text
+[![Build Status](https://travis-ci.org/vmchale/madlibs.svg?branch=master)](https://travis-ci.org/vmchale/madlibs)
 
-This is the Madlibs DSL for generating random text. There is also a vim plugin for highlighting `.mad` files. 
+This is the Madlang DSL for generating random text. There is also a vim plugin, available [here](https://github.com/vmchale/madlang-vim).  
 
-It enables you to generate random, templated text with very little effort or expertise. 
+It enables you to generate random templated text with very little effort or expertise. 
 
-It can be used for twitter bots and more productive things.
+It can be used for twitter bots and provides human-readable syntax for Markov
+chains often used in natural language processing. 
 
-### Exmaples
+## Exmaples
 
-An exmaple is worth a thousand words (?), so suppose you wanted to generate a mediocre fortune telling bot. You could write the following code:
+An exmaple is worth a thousand words, so suppose you wanted to generate a mediocre fortune telling bot. You could write the following code:
 
 ```
-
 :define person
     0.7 "A close friend will "
     0.3 "You will "
@@ -26,23 +27,28 @@
     0.2 goodfortune
 ```
 
-There are two "statements" in madlang, `:define` and `:return`. `:return` is the main string we'll be spitting back, so you're only allowed one of them per file. `:define` on the other hand can be used to make as many templates as you want. These templates are combinations of strings (enclosed in quotes) and names of other templates.
+There are two "statements" in madlang, `:define` and `:return`. `:return` is the main string we'll be spitting back, so there can be only one per file. `:define` on the other hand can be used to make multiple templates. These templates are combinations of strings (enclosed in quotes) and names of other templates.
 
-Of course, you can't have a circular reference with names - if `goodfortune` depends on `fortune` while `fortune` depends on `goodfortune`, you'll end up with either no fortune or an infinite fortune. So instead we just throw an error. 
+Of course, you can't have a circular reference with names - if `goodfortune` depends on `fortune` while `fortune` depends on `goodfortune`, we end up with either no fortune or an infinite fortune. So we throw an error.
 
-### Using the libary
+## Using the libary
 
 The main function you'll want to use is probably `runFile`; it reads a file and generates randomized text:
 
 ```
- λ> runFile "test/templates/gambling.mad"
+ λ:> runFile [] "test/templates/gambling.mad"
  "heads"
 ```
 
-Haddock documentation of all available functionality is located [here](https://hackage.haskell.org/package/madlang-0.1.0.0#readme). 
+Haddock documentation of all available functionality is located [here](https://hackage.haskell.org/package/madlang#readme).
 
 ## Installation
 
+### Releases
+
+If you're on windows or linux, grabbing release binaries is probably the
+easiest. Find them [here](https://github.com/vmchale/madlibs/releases).
+
 ### Stack
 
 Download `stack` with
@@ -51,18 +57,18 @@
 curl -sSL http://haskellstack.org | sh
 ```
 
-Then run `stack install` and you'll get the `madlang` executable installed on your path. You can even do `stack install madlang` if you'd like. 
+Then run `stack install madlang` and you'll get the `madlang` executable installed on your path.
 
 ### Use
 
-To use it, just try
+To use it, try
 
 ```
- $ madlang --input fortune-teller.mad
+ $ madlang run fortune-teller.mad
 ```
 
 You can do `madlang --help` if you want a couple other options for debugging.
 
-### Syntax Highlighting
+## Syntax Highlighting
 
-Syntax highlighting for the DSL is provided in the vim plugin [here](http://github.com/vmchale/madlang-vim). You'll have to do `:set syntax=madlang` the first time you run it but everything else should work out of the box.:
+Syntax highlighting for the DSL is provided in the vim plugin [here](http://github.com/vmchale/madlang-vim). It includes integration with [syntastic](https://github.com/vim-syntastic/syntastic).
diff --git a/bash/mkCompletions b/bash/mkCompletions
new file mode 100644
--- /dev/null
+++ b/bash/mkCompletions
@@ -0,0 +1,4 @@
+#!/bin/bash
+madlang --bash-completion-script `which madlang` > tmp
+sudo cp tmp /etc/bash_completion.d/madlang
+rm tmp
diff --git a/madlang.cabal b/madlang.cabal
--- a/madlang.cabal
+++ b/madlang.cabal
@@ -1,5 +1,5 @@
 name: madlang
-version: 2.0.0.1
+version: 2.0.1.0
 cabal-version: >=1.10
 build-type: Simple
 license: BSD3
@@ -15,9 +15,12 @@
 author: Vanessa McHale
 extra-source-files:
     README.md
-    test/templates/*.mad
+    test/templates/fortune-teller.mad
+    test/templates/gambling.mad
+    test/templates/var.mad
     test/templates/err/*.mad
     stack.yaml
+    bash/mkCompletions
 
 source-repository head
     type: git
@@ -40,7 +43,8 @@
         lens >=4.15.1 && <4.16,
         mtl >=2.2.1 && <2.3,
         ansi-wl-pprint >=0.6.7.3 && <0.7,
-        containers >=0.5.7.1 && <0.6
+        containers >=0.5.7.1 && <0.6,
+        tibetan-utils >=0.1.1.2 && <0.2
     default-language: Haskell2010
     default-extensions: OverloadedStrings DeriveGeneric DeriveFunctor
                         DeriveAnyClass
@@ -63,7 +67,7 @@
     main-is: Main.hs
     build-depends:
         base >=4.9.1.0 && <4.10,
-        madlang >=2.0.0.1 && <2.1
+        madlang >=2.0.1.0 && <2.1
     default-language: Haskell2010
     hs-source-dirs: app
 
@@ -72,7 +76,7 @@
     main-is: Spec.hs
     build-depends:
         base >=4.9.1.0 && <4.10,
-        madlang >=2.0.0.1 && <2.1,
+        madlang >=2.0.1.0 && <2.1,
         hspec >=2.4.2 && <2.5,
         megaparsec >=5.2.0 && <5.3,
         text >=1.2.2.1 && <1.3,
diff --git a/src/Text/Madlibs.hs b/src/Text/Madlibs.hs
--- a/src/Text/Madlibs.hs
+++ b/src/Text/Madlibs.hs
@@ -1,4 +1,3 @@
-
 -- | Main module exporting the relevant functions
 module Text.Madlibs (
                     -- * Parsers for `.mad` files
diff --git a/src/Text/Madlibs/Ana/Parse.hs b/src/Text/Madlibs/Ana/Parse.hs
--- a/src/Text/Madlibs/Ana/Parse.hs
+++ b/src/Text/Madlibs/Ana/Parse.hs
@@ -13,6 +13,8 @@
 import Data.Monoid
 import Control.Monad
 import Control.Monad.State
+import Text.Megaparsec.Lexer.Tibetan
+import Control.Exception hiding (try)
 
 -- | Parse a lexeme, aka deal with whitespace nicely. 
 lexeme :: Parser a -> Parser a
@@ -28,11 +30,11 @@
 
 -- | Parse a number/probability
 float :: Parser Prob
-float = lexeme L.float
+float = lexeme L.float <|> (fromIntegral <$> integer) <?> "Float"
 
 -- | Parse an integer
 integer :: Parser Integer
-integer = lexeme L.integer
+integer = lexeme (L.integer <|> parseNumber) <?> "Integer"
 
 -- | Make sure definition blocks start un-indented
 nonIndented = L.nonIndented spaceConsumer
@@ -42,11 +44,11 @@
 
 -- | Parse between quotes
 quote :: Parser a -> Parser a
-quote = between .$ (char '"') --also CAN'T have any \n AFTER
+quote = between (char '"') (char '"') -- .$ (char '"') --also CAN'T have any \n AFTER
 
 -- | Parse a keyword
 keyword :: String -> Parser String
-keyword str = (pure <$> char ':') <> (symbol str) <?> "keyword"
+keyword str = (char ':') >> (symbol str) <?> "keyword"
 
 -- | Parse a var
 var :: Parser Int
@@ -56,12 +58,12 @@
 
 -- | Parse the `define` keyword.
 define :: Parser ()
-define = (void $ nonIndented (keyword "define"))
+define = void (nonIndented (keyword "define"))
     <?> "define block"
 
 -- | Parse the `:return` keyword.
 main :: Parser ()
-main = (void $ nonIndented (keyword "return"))
+main = void (nonIndented (keyword "return"))
     <?> "return block"
 
 -- | Parse a template name (what follows a `:define` or `return` block)
@@ -76,7 +78,7 @@
         pure . PreTok $ ins `access` (v-1) -- ins !! (v - 1)
     } <|>
     do {
-        s <- quote (many $ noneOf ("\"" :: String)) ;
+        s <- quote (many $ noneOf ("\n\"" :: String)) ;
         spaceConsumer ;
         pure $ PreTok . T.pack $ s
     } 
@@ -87,7 +89,7 @@
 pair ins = do
     indentGuard
     p <- float
-    str <- some $ (preStr ins)
+    str <- some (preStr ins)
     pure (p, str) <?> "Probability/text pair"
 
 -- | Parse a `define` block
@@ -107,17 +109,19 @@
 
 -- | Parse the program in terms of `PreTok` and the `Key`s to link them.
 program :: [T.Text] -> Parser [(Key, [(Prob, [PreTok])])]
-program ins = sortKeys . checkSemantics <$> do
-    p <- many (try (definition ins) <|> ((,) "Template" <$> final ins))
-    pure p
-
-parseTreeM :: [T.Text] -> Parser (Context RandTok)
-parseTreeM ins = buildTree <$> program ins
+program ins = sortKeys <$> (checkSemantics =<< do
+    p <- many (try (definition ins) <|> ((,) "Template" <$> final ins)) -- FIXME: parse multiple `returns`? why isn't indentation working @ all?
+    lexeme eof
+    pure p)
 
 -- | Parse text as a token + context (aka a reader monad with all the other functions)
 parseTokM :: [T.Text] -> Parser (Context RandTok)
 parseTokM ins = build <$> program ins
 
+-- | Parse text as token + context
+parseTreeM :: [T.Text] -> Parser (Context RandTok)
+parseTreeM ins = buildTree <$> program ins
+
 -- | Parse text as a token
 --
 -- > f <- readFile "template.mad"
@@ -125,5 +129,6 @@
 parseTok :: FilePath -> [T.Text] -> T.Text -> Either (ParseError Char Dec) RandTok
 parseTok filename ins f = snd . head . (filter (\(i,j) -> i == "Template")) . (flip execState []) <$> runParser (parseTokM ins) filename f
 
+-- | Parse text as a token, suitable for printing as a tree..
 parseTree :: FilePath -> [T.Text] -> T.Text -> Either (ParseError Char Dec) RandTok
 parseTree filename ins f = snd . head . (filter (\(i,j) -> i == "Template")) . (flip execState []) <$> runParser (parseTreeM ins) filename f
diff --git a/src/Text/Madlibs/Ana/ParseUtils.hs b/src/Text/Madlibs/Ana/ParseUtils.hs
--- a/src/Text/Madlibs/Ana/ParseUtils.hs
+++ b/src/Text/Madlibs/Ana/ParseUtils.hs
@@ -11,17 +11,18 @@
 import Control.Exception
 import Control.Arrow
 
---consider moving Ana.ParseUtils to Cata.Sorting
+--TODO consider moving Ana.ParseUtils to Cata.Sorting
 
 -- | Convert the stuff after the number to a `RandTok`
 concatTok :: T.Text -> Context [PreTok] -> Context RandTok
 concatTok param pretoks = do
     ctx <- get
     let unList (List a) = a
-    let toRand (Name str) = List . snd . (head' str param) . (filter ((== str) . fst)) . (map (second unList)) $ ctx
+    let toRand (Name str) = List . snd . (head' str param) . (filter ((== str) . fst)) . (map (second unList)) $ ctx -- TODO move the shared functions to utils
         toRand (PreTok txt) = Value txt
     fold . (map toRand) <$> pretoks
 
+-- | Build token in tree structure, without concatenating. 
 buildTok :: T.Text -> Context [PreTok] -> Context RandTok
 buildTok param pretoks = do
     ctx <- get
@@ -30,6 +31,8 @@
         toRand (PreTok txt) = Value txt
     List . zip ([1..]) . (map toRand) <$> pretoks
 
+-- | Build the token without concatenating, yielding a `RandTok` suitable to be
+-- printed as a tree. 
 buildTree :: [(Key, [(Prob, [PreTok])])] -> Context RandTok
 buildTree list@[(key,pairs)] = do
     toks <- mapM (\(i,j) -> buildTok key (pure j)) pairs
@@ -40,8 +43,6 @@
     y <- buildTree [x]
     ys <- pure <$> buildTree xs
     pure . List . zip ([1..]) $ (y:ys)
-
--- basically just substitute? 
 
 -- | Given keys naming the tokens, and lists of `PreTok`, build our `RandTok`
 build :: [(Key, [(Prob, [PreTok])])] -> Context RandTok
diff --git a/src/Text/Madlibs/Cata/SemErr.hs b/src/Text/Madlibs/Cata/SemErr.hs
--- a/src/Text/Madlibs/Cata/SemErr.hs
+++ b/src/Text/Madlibs/Cata/SemErr.hs
@@ -6,20 +6,41 @@
 import Text.PrettyPrint.ANSI.Leijen
 import Control.Exception
 import qualified Data.Text as T
+import Control.Monad
+import qualified Data.Set as S
+import Text.Megaparsec.Text
+import Text.Megaparsec.Prim
+import Text.Megaparsec.Error
 
 -- | Datatype for a semantic error
-data SemanticError = OverloadedReturns | CircularFunctionCalls T.Text T.Text | ProbSum T.Text | InsufficientArgs Int Int
+data SemanticError = OverloadedReturns | CircularFunctionCalls T.Text T.Text | InsufficientArgs Int Int
     deriving (Typeable)
 
---also consider overloading parseError tbqh
 -- | display a `SemanticError` nicely with coloration & whatnot
 instance Show SemanticError where
     show OverloadedReturns = show $ semErrStart <> text "File contains multiple declarations of :return"
     show (CircularFunctionCalls f1 f2) = show $ semErrStart <> text "Circular function declaration between:" <> indent 4 (yellow $ (text' f1) <> (text ", ") <> (text' f2))
     show (InsufficientArgs i j) = show $ semErrStart <> text "Insufficent arguments from the command line, given " <> (text . show $ i) <> ", expected at least " <> (text . show $ j)
-    show (ProbSum f) = show $ semErrStart <> text "Function's options do not sum to 1:\n" <> indent 4 (yellow (text' f))
-    --we probably want to do our instance of `Show` for `ParseError` since that will let us color the position nicely @ least
 
+-- | Derived via our show instance;
+instance Exception SemanticError where
+
+-- | Throw custom error given by string, within the parser
+customError :: String -> Parser a
+customError = failure S.empty S.empty . S.singleton . representFail
+
+-- | Throw `OverloadedReturns` error within parser
+overloadedReturns :: Parser a
+overloadedReturns = customError . show $ OverloadedReturns
+
+-- | Throws argument for circular function calls
+circularFunctionCalls :: T.Text -> T.Text -> Parser a
+circularFunctionCalls f1 f2 = customError . show $ CircularFunctionCalls f1 f2
+
+-- | Throws error for insufficient arguments
+insufficientArgs :: Int -> Int -> Parser a
+insufficientArgs i j = customError . show $ InsufficientArgs i j
+
 -- | Constant to start `SemanticError`s
 semErrStart :: Doc
 semErrStart = dullred (text "\n  Semantic Error: ")
@@ -28,22 +49,10 @@
 text' :: T.Text -> Doc
 text' = text . T.unpack
 
--- | derived exception instance
-instance Exception SemanticError
-
 -- | big semantics checker that sequences stuff
-checkSemantics :: [(Key, [(Prob, [PreTok])])] -> [(Key, [(Prob, [PreTok])])]
-checkSemantics = foldr (.) id [ checkProb
-                              , checkReturn ]
-
--- checker to verify we have the right number of command-line args
--- checkArgs :: [(Key, [(Prob, [PreTok])])] -> [(Key, [(Prob, [PreTok])])]
-
--- | checker to verify probabilities sum to 1
-checkProb :: [(Key, [(Prob, [PreTok])])] -> [(Key, [(Prob, [PreTok])])]
-checkProb = map (\(i,j) -> if sumProb j then (i,j) else throw (ProbSum i))
---potentially consider throwing mult. errors at once obvi
-
+checkSemantics :: [(Key, [(Prob, [PreTok])])] -> Parser [(Key, [(Prob, [PreTok])])]
+checkSemantics = foldr (<=<) pure [ checkReturn
+                                  ]
 -- | helper to filter out stuff that doesn't
 sumProb :: [(Prob, [PreTok])] -> Bool
 sumProb = ((==1) . sum . (map fst))
@@ -54,16 +63,18 @@
 head' _ _ (x:xs) = x
 head' f1 f2 _ = throw (CircularFunctionCalls f1 f2)
 
+-- | Access argument, or throw error if the list is too short. 
 access :: [a] -> Int -> a
 access xs i = if (i >= length xs) then throw (InsufficientArgs (length xs) (i+1)) else xs !! i
 
 -- | checker to verify there is at most one `:return` statement
-checkReturn :: [(Key, [(Prob, [PreTok])])] -> [(Key, [(Prob, [PreTok])])]
+checkReturn :: [(Key, [(Prob, [PreTok])])] -> Parser [(Key, [(Prob, [PreTok])])]
 checkReturn keys
-    | singleReturn keys = keys
-    | otherwise = throw OverloadedReturns
+    | singleReturn keys = pure keys
+    | otherwise = overloadedReturns
 
 -- | Checks that we have at most one `:return` template in the file
 singleReturn :: [(Key, [(Prob, [PreTok])])] -> Bool
 singleReturn = singleton . (filter ((=="Template") . fst))
-    where singleton = not . null
+    where singleton [a] = True
+          singleton _   = False
diff --git a/src/Text/Madlibs/Exec/Main.hs b/src/Text/Madlibs/Exec/Main.hs
--- a/src/Text/Madlibs/Exec/Main.hs
+++ b/src/Text/Madlibs/Exec/Main.hs
@@ -19,11 +19,12 @@
                        , input :: FilePath 
                        }
 
+-- | datatype for the subcommands
 data Subcommand = Debug { version :: Bool }
                 | Run { rep :: Maybe Int , clInputs :: [String] }
                 | Lint { clInputs :: [String] }
-                -- Repeat { rep :: Maybe Int }
 
+-- | Parser for command-line options for the program
 orders :: Parser Program
 orders = Program
     <$> (hsubparser
@@ -34,6 +35,7 @@
         (metavar "FILEPATH"
         <> help "File path to madlang template"))
 
+-- | Parser for debug subcommand
 debug :: Parser Subcommand
 debug = Debug
     <$> switch
@@ -41,6 +43,7 @@
         <> short 'v'
         <> help "Show version information")
 
+-- | Parser for the run subcommand
 temp :: Parser Subcommand
 temp = Run
     <$> (optional $ read <$> strOption
@@ -53,6 +56,7 @@
         <> metavar "VAR"
         <> help "command-line inputs to the template."))
 
+-- | Parser for the lint subcommand
 lint :: Parser Subcommand
 lint = Lint
     <$> (many $ strOption
@@ -63,10 +67,8 @@
 -- | Main program action
 runMadlang :: IO ()
 runMadlang = execParser wrapper >>= template 
-    --case rep . sub $ x of
-    --    (Just n) -> replicateM_ n $ template x
-    --    Nothing -> template x
 
+-- | Wraps parser with help parser
 wrapper = info (helper <*> orders)
     (fullDesc
     <> progDesc "Madlang templating language"
@@ -77,15 +79,15 @@
 template rec = do
     let filepath = input $ rec
     let ins = map T.pack $ (clInputs . sub $ rec)
-    parsed <- parseFile ins filepath
     case sub rec of
         (Run reps _) -> do
-            replicateM_ (maybe 1 id reps) $ runFile ins filepath >>= TIO.putStrLn -- fix so it parses once!! either show run $ parsed 
+            parsed <- parseFile ins filepath
+            replicateM_ (maybe 1 id reps) $ runFile ins filepath >>= TIO.putStrLn 
         (Debug _) -> do
-            putStrLn . (either show (drawTree . tokToTree 1.0)) =<< makeTree ins filepath -- parsed
-            --print parsed
+            putStr . (either show (drawTree . tokToTree 1.0)) =<< makeTree ins filepath -- parsed
         (Lint _) -> do
-            putStrLn $ either show (const "No errors found.") parsed
+            parsed <- parseFile ins filepath
+            putStrLn $ either parseErrorPretty (const "No syntax errors found.") parsed
 
 -- | Generate randomized text from a template
 templateGen :: FilePath -> [T.Text] -> T.Text -> Either (ParseError Char Dec) (IO T.Text)
@@ -104,6 +106,7 @@
     let val = parseTok filepath ins txt
     pure val
 
+-- | Parse a template into a RandTok suitable to be displayed as a tree
 makeTree :: [T.Text] -> FilePath -> IO (Either (ParseError Char Dec) RandTok)
 makeTree ins filepath = do
     txt <- readFile' filepath
diff --git a/src/Text/Madlibs/Internal/Types.hs b/src/Text/Madlibs/Internal/Types.hs
--- a/src/Text/Madlibs/Internal/Types.hs
+++ b/src/Text/Madlibs/Internal/Types.hs
@@ -27,28 +27,14 @@
 data RandTok = List [(Prob, RandTok)] | Value T.Text
     deriving (Show, Eq)
 
+-- | Function to transform a `RandTok` into a `Tree String` so that it can be pretty-printed. 
+--
+-- > tokToTree 1.0 tok
 tokToTree :: Prob -> RandTok -> Tree String
 tokToTree p (Value a) = Node ((take 4 . show . min 1.0) p ++ " " ++ show a) []
 tokToTree p (List [(_,Value a)]) = Node ((take 4 . show . min 1.0) p ++ " " ++ show a) []
-tokToTree p (List xs) = Node (take 4 . show . min 1.0 $ p) (map (\(prob, val) -> tokToTree prob val) xs) -- (on (tokToTree .* fst -.* snd) (flip ($))) xs)
-
--- | Neat 2-dimensional drawing of a parsed tree.
-{--
-drawTree :: Tree String -> String
-drawTree  = unlines . draw
-
-
-draw :: Tree String -> [String]
-draw (Node x ts0) = lines x ++ drawSubTrees ts0
-  where
-    drawSubTrees [] = []
-    drawSubTrees [t] =
-        "|" : shift "`- " "   " (draw t)
-    drawSubTrees (t:ts) =
-        "|" : shift "+- " "|  " (draw t) ++ drawSubTrees ts
+tokToTree p (List xs) = Node (take 4 . show . min 1.0 $ p) (map (uncurry tokToTree) xs)
 
-    shift first other = zipWith (++) (first : repeat other)
---}
 -- | Make `RandTok` a monoid so we can append them together nicely (since they do generate text). 
 --
 -- > (Value "Hello") <> (List [(0.5," you"), (0.5, " me")])
diff --git a/src/Text/Madlibs/Internal/Utils.hs b/src/Text/Madlibs/Internal/Utils.hs
--- a/src/Text/Madlibs/Internal/Utils.hs
+++ b/src/Text/Madlibs/Internal/Utils.hs
@@ -23,6 +23,7 @@
     mempty = pure mempty
     mappend x y = mappend <$> x <*> y
 
+-- | Normalize pre-tokens/corresponding probabilities
 normalize :: [(Prob, [PreTok])] -> [(Prob, [PreTok])]
 normalize list = map (over _1 (/total)) list
     where total = sum . map fst $ list
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -4,6 +4,8 @@
 # For advanced use and comprehensive documentation of the format, please see:
 # http://docs.haskellstack.org/en/stable/yaml_configuration/
 
+# A warning or info to be displayed to the user on config load.
+
 # Resolver to choose a 'specific' stackage snapshot or a compiler version.
 # A snapshot resolver dictates the compiler version and the set of packages
 # to be used for project dependencies. For example:
@@ -39,7 +41,8 @@
 - '.'
 # Dependency packages to be pulled from upstream that are not in the resolver
 # (e.g., acme-missiles-0.3)
-extra-deps: []
+extra-deps:
+- tibetan-utils-0.1.1.2
 
 # Override default flag values for local packages and extra-deps
 flags: {}
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -9,70 +9,60 @@
 import Data.Function
 import Control.Exception
 import qualified Data.Text as T
+import qualified Data.Text.IO as TIO
 import System.IO.Unsafe
 
 main :: IO ()
 main = hspec $ do
     describe "parseTok" $ do
         parallel $ it "parses a .mad string" $ do
-            parseTok "" [] madFile `shouldParse` (List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])])
+            file <- madFile
+            parseTok "" [] file `shouldParse` (List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])])
+        parallel $ it "parses tibetan numerals" $ do
+            file <- madFileTibetan
+            parseTok "" [] file `shouldParse` (List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])])
         parallel $ it "fails when quotes aren't closed" $ do
-            parseTok "" [] `shouldFailOn` madFileFailure
+            file <- madFileFailure
+            parseTok "" [] `shouldFailOn` file
         parallel $ it "parses when functions are out of order" $ do
-            parseTok "" [] `shouldSucceedOn` madComplexFile
+            file <- madComplexFile
+            parseTok "" [] `shouldSucceedOn` file
         parallel $ it "returns a correct string from the template when evaluating a token" $ do
-            (testIO . run) exampleTok `shouldSatisfy` (\a -> on (||) (a ==) "heads" "tails")
+            (run) exampleTok >>= (`shouldSatisfy` (\a -> on (||) (a ==) "heads" "tails"))
         parallel $ it "throws exception when two `:return`s are declared" $ do
-            (parseTok "" [] `shouldFailOn` semErrFile) `shouldThrow` semErr
+            file <- semErrFile
+            (parseTok "" [] `shouldFailOn` file) 
         parallel $ it "substitutes a variable correctly" $ do
-            parseTok "" ["maxine"] `shouldSucceedOn` madVar
+            file <- madVar
+            parseTok "" ["maxine"] `shouldSucceedOn` file
         parallel $ it "fails when variables are not passed in" $ do
-            (parseTok "" [] `shouldFailOn` madVar) `shouldThrow` anyException
+            file <- madVar
+            (parseTok "" [] `shouldFailOn` file) `shouldThrow` anyException
 
 semErr :: Selector SemanticError
 semErr = const True
 
+-- | Read a file in as a `Text`
+readFile' :: FilePath -> IO T.Text
+readFile' = (fmap T.pack) . readFile
+
 exampleTok :: RandTok
 exampleTok = List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])]
 
-madFile :: T.Text
-madFile = ":define something\n    0.5 \"heads\"\n    0.5 \"tails\"\n:return\n    1.0 something"
+madFile :: IO T.Text
+madFile = readFile' "test/templates/gambling.mad" 
 
-madFileFailure :: T.Text
-madFileFailure = ":define something\
-\    0.5 \"heads\"\
-\    0.5 \"tails\
-\:return\
-\    1.0 something"
+madFileTibetan :: IO T.Text
+madFileTibetan = readFile' "test/templates/ཤོ.mad"
 
-madComplexFile :: T.Text
-madComplexFile = ":define person\
-\    0.7 \"I will \"\
-\    0.3 \"You will \"\
-\:define goodfortune\
-\    0.1 person \"make nice things happen today\"\
-\    0.9 \"nice things will happen today\"\
-\:define fortune\
-\    0.5 \"drink a boatload of milk\"\
-\    0.5 \"get heckin angry\"\
-\:return\
-\    0.8 person fortune\
-\    0.2 goodfortune"
+madFileFailure :: IO T.Text
+madFileFailure = readFile' "test/templates/err/bad.mad"
 
-semErrFile :: T.Text
-semErrFile = ":define something\
-\    0.5 \"heads\"\
-\    0.5 \"tails\"\
-\:return\
-\    1.0 something\
-\:return\
-\    0.5 something\
-\    0.5 \"parallel$ it doesn't matter b/c this is gonna blow up in our faces anyways\""
+madComplexFile :: IO T.Text
+madComplexFile = readFile' "test/templates/gambling.mad"
 
-madVar :: T.Text
-madVar = ":return\
-\    1.0 $1 \" is a good doggo.\""
+semErrFile :: IO T.Text
+semErrFile = readFile' "test/templates/err/sem-err.mad"
 
--- | for the testing framework; to 
-testIO :: IO a -> a
-testIO = unsafePerformIO
+madVar :: IO T.Text
+madVar = readFile' "test/templates/var.mad"
diff --git a/test/templates/err/bad-sum.mad b/test/templates/err/bad-sum.mad
deleted file mode 100644
--- a/test/templates/err/bad-sum.mad
+++ /dev/null
@@ -1,5 +0,0 @@
-:define something
-    0.5 "heads"
-    0.7 "tails"
-:return
-    1.0 something
diff --git a/test/templates/err/sem-err.mad b/test/templates/err/sem-err.mad
--- a/test/templates/err/sem-err.mad
+++ b/test/templates/err/sem-err.mad
@@ -1,6 +1,6 @@
 :define something
     0.5 "heads"
-    0.5 "tails
+    0.5 "tails"
 :return
     1.0 something
 :return
diff --git a/test/templates/fortune-teller.mad b/test/templates/fortune-teller.mad
--- a/test/templates/fortune-teller.mad
+++ b/test/templates/fortune-teller.mad
@@ -11,8 +11,5 @@
     0.8 person fortune
     0.2 goodfortune
 {#
-:define copies
-    :replicate person
-        (1) 0.3
-        (2) 0.7
+block comment
 #}
