diff --git a/Text/Parsec/Indent.hs b/Text/Parsec/Indent.hs
--- a/Text/Parsec/Indent.hs
+++ b/Text/Parsec/Indent.hs
@@ -1,96 +1,89 @@
 {-# LANGUAGE FlexibleContexts #-}
 module Text.Parsec.Indent (
-    IndentParserT,
-    withBlock, withLineFold,
-    withBlock', withLineFold',
-    block, lineFold,
-    manyLine, manyIndent,
-    foldLine, foldLine3, foldLine4,
-    foldLine5, (<+/>), (<-/>), runIndent
+    -- $doc
+    
+    -- * Types
+    IndentParserT, runIndent,
+    -- * Blocks
+    withBlock, withBlock', block,
+    -- * Indentation Checking
+    indented, same, sameOrIndented, checkIndent, withPos,
+    -- * Paired characters
+    indentBrackets, indentAngles, indentBraces, indentParens,
+    -- * Line Fold Chaining
+    -- | Any chain using these combinators must used with 'withPos'
+    (<+/>), (<-/>), (<*/>)
     ) where
 import Text.Parsec
 import Text.Parsec.Pos
+import Text.Parsec.Token
 import Control.Monad.State
 import Control.Concatenative
-
-{-| 
-
-A module to construct indentation aware parsers. Many programming
-language have indentation based syntax rules e.g. python and Haskell.
-This module exports combinators to create such parsers. 
-
-The input source can be thought of as a list of tokens. Abstractly
-each token occurs at a line and a column and has a width. The column
-number of a token measures is indentation. If t1 and t2 are two tokens
-then we say that indentation of t1 is more than t2 if the column
-number of occurrence of t1 is greater than that of t2.
-
-Currently this module supports two kind of indentation based syntactic
-structures which we now describe:
-
-[Block] A block of indentation /c/ is a sequence of tokens with
-indentation at least /c/.  Examples for a block is a where clause of
-Haskell with no explicit braces.
-
-[Line fold] A line fold starting at line /l/ and indentation /c/ is a
-sequence of tokens that start at line /l/ and possibly continue to
-subsequent lines as long as the indentation is greater than /c/. Such
-a sequence of lines need to be /folded/ to a single line. An example
-is MIME headers. Line folding based binding separation is used in
-Haskell as well.
+import Debug.Trace
 
--}
+-- $doc
+-- A module to construct indentation aware parsers. Many programming
+-- language have indentation based syntax rules e.g. python and Haskell.
+-- This module exports combinators to create such parsers. 
+-- 
+-- The input source can be thought of as a list of tokens. Abstractly
+-- each token occurs at a line and a column and has a width. The column
+-- number of a token measures is indentation. If t1 and t2 are two tokens
+-- then we say that indentation of t1 is more than t2 if the column
+-- number of occurrence of t1 is greater than that of t2.
+-- 
+-- Currently this module supports two kind of indentation based syntactic
+-- structures which we now describe:
+-- 
+-- [Block] A block of indentation /c/ is a sequence of tokens with
+-- indentation at least /c/.  Examples for a block is a where clause of
+-- Haskell with no explicit braces.
+-- 
+-- [Line fold] A line fold starting at line /l/ and indentation /c/ is a
+-- sequence of tokens that start at line /l/ and possibly continue to
+-- subsequent lines as long as the indentation is greater than /c/. Such
+-- a sequence of lines need to be /folded/ to a single line. An example
+-- is MIME headers. Line folding based binding separation is used in
+-- Haskell as well.
 
+-- | Indentation sensitive parser type. Usually @ m @ will
+--   be @ Identity @ as with any @ ParsecT @
 type IndentParserT s u m a = ParsecT s u (StateT SourcePos m) a
-
--- | @ 'withLineFold' f a p @ parses @ a @ followed by any number of @ p @
---   that can wrap onto subsequent indented lines, combined by @ f @
-withLineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->
-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
-withLineFold f a p = withPos $ do
+    
+-- | @ 'withBlock' f a b p @ parses @ a @ and optionally
+--   @ b @ followed by an indented block of @ p @
+--   , combining them with @ f @
+withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->
+    IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m c
+withBlock f a b p = withPos $ do
     r1 <- a
-    r2 <- many (sameOrIndented >> p)
+    r2 <- option [] (b >> indented >> block p)
     return (f r1 r2)
 
--- | Like 'withLineFold', but throws away initial parse result
-withLineFold' :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
-withLineFold' = withLineFold (flip const)
-
 -- | Like 'withBlock', but throws away initial parse result
 withBlock' :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m [b]
+    IndentParserT s u m a -> IndentParserT s u m x -> IndentParserT s u m b -> IndentParserT s u m [b]
 withBlock' = withBlock (flip const)
 
--- | Parses one or more times, continuing in subsequent indented lines
-lineFold :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
-lineFold = withLineFold' (return ())
-    
--- | @ 'withBlock' f a p @ parses @ a @ followed by an indented block of @ p @
---   and combines them with @ f @
-withBlock :: (Stream s (StateT SourcePos m) Char, Monad m) => (a -> [b] -> c) ->
-    IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
-withBlock f a p = withPos $ do
-    r1 <- a
-    r2 <- option [] (indented >> block p)
-    return (f r1 r2)
-
+-- | Parses only when indented past the level of the reference
 indented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
 indented = do
     pos <- getPosition
     s <- get
-    if biAp sourceColumn (<) pos s then mzero else do
+    if biAp sourceColumn (<=) pos s then parserFail "not indented" else do
         put $ setSourceLine s (sourceLine pos)
         return ()
 
+-- | Parses only when indented past the level of the reference or on the same line
 sameOrIndented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
 sameOrIndented = same <|> indented
 
+-- | Parses only on the same line as the reference
 same :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
 same = do
     pos <- getPosition
     s <- get
-    if biAp sourceLine (==) pos s then return () else mzero
+    if biAp sourceLine (==) pos s then return () else parserFail "over one line"
     
 -- | Parses a block of lines at the same indentation level
 block :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
@@ -98,6 +91,7 @@
     r <- many1 (checkIndent >> p)
     return r
 
+-- | Parses using the current location for indentation reference
 withPos :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m a
 withPos x = do
     a <- get
@@ -105,73 +99,44 @@
     r <- put p >> x
     put a >> return r
 
+-- | Ensures the current indentation level matches that of the reference
 checkIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
 checkIndent = do
     s <- get
     p <- getPosition
-    if biAp sourceColumn (==) p s then return () else mzero
+    if biAp sourceColumn (==) p s then return () else parserFail "indentation doesn't match"
 
 -- | Run the result of an indentation sensitive parse
 runIndent :: Monad m => SourceName -> StateT SourcePos m a -> m a
 runIndent s = flip evalStateT (initialPos s)
 
--- | Parses many occurances of p without using more than one line
-manyLine :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
-manyLine p = withPos (many (same >> p))
-
--- | Parses many occurances of p, indenting if over one line
-manyIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
-manyIndent p = withPos (many (sameOrIndented >> p))
-
--- | Parses two arguments for @ f @ possibly wrapping onto subsequent lines
-foldLine :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    (a -> b -> c) -> IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m c
-foldLine f a b = withPos $ do
-    r1 <- a
-    r2 <- sameOrIndented >> b
-    return $ f r1 r2
-
--- | Parses three arguments for @ f @ possibly wrapping onto subsequent lines
-foldLine3 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    (a -> b -> c -> d) -> IndentParserT s u m a -> IndentParserT s u m b
-    -> IndentParserT s u m c -> IndentParserT s u m d
-foldLine3 f a b c = withPos $ do
-    r1 <- a
-    r2 <- sameOrIndented >> b
-    r3 <- sameOrIndented >> c
-    return $ f r1 r2 r3
-
--- | Parses four arguments for @ f @ possibly wrapping onto subsequent lines
-foldLine4 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    (a -> b -> c -> d -> e) -> IndentParserT s u m a -> IndentParserT s u m b
-    -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e
-foldLine4 f a b c d = withPos $ do
-    r1 <- a
-    r2 <- sameOrIndented >> b
-    r3 <- sameOrIndented >> c
-    r4 <- sameOrIndented >> d 
-    return $ f r1 r2 r3 r4
-
--- | Parses four arguments for @ f @ possibly wrapping onto subsequent lines
-foldLine5 :: (Stream s (StateT SourcePos m) Char, Monad m) =>
-    (a -> b -> c -> d -> e -> f) -> IndentParserT s u m a -> IndentParserT s u m b
-    -> IndentParserT s u m c -> IndentParserT s u m d -> IndentParserT s u m e
-    -> IndentParserT s u m f
-foldLine5 f a b c d e = withPos $ do
-    r1 <- a
-    r2 <- sameOrIndented >> b
-    r3 <- sameOrIndented >> c
-    r4 <- sameOrIndented >> d
-    r5 <- sameOrIndented >> e
-    return $ f r1 r2 r3 r4 r5
-
--- | '<+/>' is to foldLine as 'ap' is to 'liftM2'
+-- | '<+/>' is to indentation sensitive parsers what 'ap' is to monads
 (<+/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>
     IndentParserT s u m (a -> b) -> IndentParserT s u m a -> IndentParserT s u m b
-(<+/>) = foldLine id
+a <+/> b = ap a (sameOrIndented >> b)
 
 -- | '<-/>' is like '<+/>', but doesn't apply the function to the parsed value
 (<-/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>
     IndentParserT s u m a -> IndentParserT s u m b -> IndentParserT s u m a
-(<-/>) = foldLine const
+a <-/> b = liftM2 const a (sameOrIndented >> b)
 
+-- | Like '<+/>' but applies the second parser many times
+(<*/>) :: (Stream s (StateT SourcePos m) Char, Monad m) =>
+    IndentParserT s u m ([a] -> b) -> IndentParserT s u m a -> IndentParserT s u m b
+a <*/> b = ap a (many (sameOrIndented >> b))
+
+-- | parses with surrounding brackets
+indentBrackets :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+indentBrackets lexer p = withPos $ return id <-/> symbol lexer "[" <+/> p <-/> symbol lexer "]"
+
+-- | parses with surrounding angle brackets
+indentAngles :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+indentAngles lexer p = withPos $ return id <-/> symbol lexer "<" <+/> p <-/> symbol lexer ">"
+
+-- | parses with surrounding braces
+indentBraces :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+indentBraces lexer p = withPos $ return id <-/> symbol lexer "{" <+/> p <-/> symbol lexer "}"
+
+-- | parses with surrounding parentheses 
+indentParens :: (Stream s (StateT SourcePos m) Char, Monad m) => GenTokenParser s u (StateT SourcePos m) -> IndentParserT s u m a -> IndentParserT s u m a
+indentParens lexer p = withPos $ return id <-/> symbol lexer "(" <+/> p <-/> symbol lexer ")"
diff --git a/indents.cabal b/indents.cabal
--- a/indents.cabal
+++ b/indents.cabal
@@ -7,7 +7,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.2.0
+Version:             0.3.0
 
 -- A short (one-line) description of the package.
 Synopsis:            indentation sensitive parser-combinators for parsec
