diff --git a/src/Text/Render.hs b/src/Text/Render.hs
--- a/src/Text/Render.hs
+++ b/src/Text/Render.hs
@@ -1,14 +1,22 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
 module Text.Render (
-    Render(..),
+    Render(..), Indenter,
+    indented, wrapIndented, inNewLine, renderIndented,
+    renderIndentedStartingAt,
     renderTicks
   ) where
 
+import ClassyPrelude
 import qualified Prelude as P
-import Prelude (($), (.), map, Int, Double, Functor(..), Show(..),
-                Eq(..), Bool, Integer, Double, Monad(..))
 import Control.Monad.Trans (MonadIO(..))
-import Data.Monoid
+import Control.Monad.Reader (ReaderT(..), MonadReader(..), (<=<), (>=>), ask,
+                             asks, runReaderT)
+import Control.Monad.Writer (WriterT(..), MonadWriter(..), runWriterT)
+import Control.Monad.State.Strict (MonadState, StateT, State, get, gets,
+                                   modify, put, liftM, liftIO, runState,
+                                   runStateT, execState, execStateT,
+                                   evalState, evalStateT)
 import Data.Text (Text)
 import qualified Data.Text as T
 import Text.Parsec (ParseError)
@@ -20,13 +28,18 @@
   -- | Render the object as a `Text`.
   render :: a -> Text
   render = T.pack . P.show
+
   -- | Many types of objects need to be rendered in parentheses.
   renderParens :: a -> Text
   renderParens = render
+
   -- | Render in the `IO` monad. Useful for objects containing IORefs.
   renderIO :: MonadIO m => a -> m Text
   renderIO = return . render
 
+  renderI :: a -> Indenter
+  renderI = tell . render
+
 instance Render Int
 instance Render Bool
 instance Render Integer
@@ -41,3 +54,32 @@
 -- | Renders and surrounds in backticks. Useful for printing user input.
 renderTicks :: Render a => a -> Text
 renderTicks x = "`" <> render x <> "`"
+
+type Indenter = ReaderT Int (WriterT Text (State Int)) ()
+
+indented :: Indenter -> Indenter
+indented action = do
+  c <- get
+  put (c+1)
+  action
+  put c
+
+inNewLine :: Indenter -> Indenter
+inNewLine action = do
+  ilevel <- ask
+  current <- get
+  tell $ "\n" <> T.replicate (ilevel * current) " "
+  action
+
+wrapIndented :: Render a => Text -> Text -> [a] -> Indenter
+wrapIndented start finish things = do
+  tell start
+  indented $ mapM_ (inNewLine . renderI) things
+  inNewLine $ tell finish
+
+renderIndented :: Render a => Int -> a -> Text
+renderIndented = renderIndentedStartingAt 0
+
+renderIndentedStartingAt :: Render a => Int -> Int -> a -> Text
+renderIndentedStartingAt start level e =
+  snd $ evalState (runWriterT (runReaderT (renderI e) level)) start
diff --git a/text-render.cabal b/text-render.cabal
--- a/text-render.cabal
+++ b/text-render.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                text-render
-version:             0.1.0.1
+version:             0.1.0.2
 synopsis:            A type class for rendering objects as text, pretty-printing, etc.
 -- description:
 homepage:            http://github.com/thinkpad20/text-render
@@ -21,6 +21,6 @@
   hs-source-dirs:      src
 -- other-modules:
   -- other-extensions:
-  build-depends:       base >=4.8 && <4.9, text, parsec, mtl
+  build-depends:       base >=4.8 && <4.9, text, parsec, mtl, classy-prelude
   -- hs-source-dirs:
   default-language:    Haskell2010
