diff --git a/Text/Parsec/Indent.hs b/Text/Parsec/Indent.hs
--- a/Text/Parsec/Indent.hs
+++ b/Text/Parsec/Indent.hs
@@ -1,7 +1,12 @@
 {-# LANGUAGE FlexibleContexts #-}
 module Text.Parsec.Indent (
-    IndentParserT, block, lineFold,
-    manyLine, runIndent
+    IndentParserT,
+    withBlock, withLineFold,
+    withBlock', withLineFold',
+    block, lineFold,
+    manyLine, manyIndent,
+    foldLine, foldLine3, foldLine4,
+    foldLine5, (<+/>), (<-/>), runIndent
     ) where
 import Text.Parsec
 import Text.Parsec.Pos
@@ -38,43 +43,67 @@
 
 type IndentParserT s u m a = ParsecT s u (StateT SourcePos m) a
 
--- | 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]
-block p = do
-    a <- setStart
-    r <- many (checkIndent >> p)
-    put a
-    return r
+-- | @ '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
+    r1 <- a
+    r2 <- many (sameOrIndented >> p)
+    return (f r1 r2)
 
--- | Continues parsing indented below a line
+-- | 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]
+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 p = do
-    a <- setStart
-    r <- blockOrNewLine p
-    put a
-    return r
+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)
 
-blockOrNewLine :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m [a]
-blockOrNewLine p = do
-    a <- p
-    s <- get
+indented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+indented = do
     pos <- getPosition
-    liftM (a:) $ if biAp sourceLine (==) pos s then blockOrNewLine p else liftM concat (block (manyLine p))
+    s <- get
+    if biAp sourceColumn (<) pos s then mzero else do
+        put $ setSourceLine s (sourceLine pos)
+        return ()
 
--- | 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 = setStart >> f where
-    f = do
-        s <- get
-        pos <- getPosition
-        if biAp sourceLine (==) pos s then liftM2 (:) p f else many (char ' ') >> return []
+sameOrIndented :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
+sameOrIndented = same <|> indented
 
-setStart :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m SourcePos
-setStart = do
+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
+    
+-- | 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]
+block p = withPos $ do
+    r <- many1 (checkIndent >> p)
+    return r
+
+withPos :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m a -> IndentParserT s u m a
+withPos x = do
     a <- get
     p <- getPosition
-    (put p)
-    return a
+    r <- put p >> x
+    put a >> return r
 
 checkIndent :: (Stream s (StateT SourcePos m) Char, Monad m) => IndentParserT s u m ()
 checkIndent = do
@@ -85,3 +114,64 @@
 -- | 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'
+(<+/>) :: (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
+
+-- | '<-/>' 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
+
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.1.1
+Version:             0.2.0
 
 -- A short (one-line) description of the package.
 Synopsis:            indentation sensitive parser-combinators for parsec
