diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -192,6 +192,8 @@
 - If `variable` is an array, the material inside the loop will
   be evaluated repeatedly, with `variable` being set to each
   value of the array in turn, and concatenated.
+- If `variable` is a map, the material inside will be set to
+  the map.
 - If the value of the associated variable is not an array or
   a map, a single iteration will be performed on its value.
 
@@ -207,6 +209,10 @@
 ${ for(foo.bar) }
   - ${ foo.bar.last }, ${ foo.bar.first }
 ${ endfor }
+
+$for(mymap)$
+$it.name$: $it.office$
+$endfor$
 ```
 
 You may optionally specify a separator between consecutive
@@ -362,11 +368,7 @@
 $for(metadata/pairs)$
 - $it.key$: $it.value$
 $endfor$
-```
 
-Filters may also be applied to the results of partials:
-
-```
 $employee:name()/uppercase$
 ```
 
@@ -395,11 +397,9 @@
   value was an array, the `key` will be the array index,
   starting with 1.
 
-- `uppercase`:  Converts a textual value to uppercase,
-  and has no effect on other values.
+- `uppercase`:  Converts text to uppercase.
 
-- `lowercase`:  Converts a textual value to lowercase,
-  and has no effect on other values.
+- `lowercase`:  Converts text to lowercase.
 
 - `length`:  Returns the length of the value:  number
   of characters for a textual value, number of elements
@@ -408,21 +408,20 @@
 - `reverse`:  Reverses a textual value or array,
   and has no effect on other values.
 
-- `chomp`:  Removes trailing newlines (and breakable space)
-  from a textual value, and has no effect on other values.
+- `chomp`:  Removes trailing newlines (and breakable space).
 
-- `alpha`:  Converts a textual value that can be
-  read as an integer into a lowercase alphabetic
-  character `a..z` (mod 26), and has no effect on
-  other values.  This can be used to get lettered
+- `nowrap`:  Disables line wrapping on breakable spaces.
+
+- `alpha`:  Converts textual values that can be
+  read as an integer into lowercase alphabetic
+  characters `a..z` (mod 26). This can be used to get lettered
   enumeration from array indices.  To get uppercase
   letters, chain with `uppercase`.
 
-- `roman`:  Converts a textual value that can be
-  read as an integer into a lowercase roman numerial,
-  and has no effect on other values.  This can be used
-  to get lettered enumeration from array indices.  To
-  get uppercase roman, chain with `uppercase`.
+- `roman`:  Converts textual values that can be
+  read as an integer into lowercase roman numerials.
+  This can be used to get lettered enumeration from array indices.
+  To get uppercase roman, chain with `uppercase`.
 
 - `left n "leftborder" "rightborder"`:  Renders a textual value
   in a block of width `n`, aligned to the left, with an optional
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,17 @@
 # doctemplates
 
+## 0.7.2
+
+  * Add `nowrap` filter.
+
+  * Improve `alpha`, `roman`, `uppercase`, `lowercase` filters so they
+    apply recursively within a list or map.
+
+  * Allow `for` loops to bind map value.  In this case there is no
+    iteration, but the anophoric variable 'it' is assigned, which may
+    help in using filters that destructure a string into a map (if
+    we add any).
+
 ## 0.7.1
 
   * Add `chomp` filter.
diff --git a/doctemplates.cabal b/doctemplates.cabal
--- a/doctemplates.cabal
+++ b/doctemplates.cabal
@@ -1,5 +1,5 @@
 name:                doctemplates
-version:             0.7.1
+version:             0.7.2
 synopsis:            Pandoc-style document templates
 description:         This is the text templating system used by pandoc.
                      It supports variable interpolation, iteration,
@@ -54,6 +54,7 @@
   build-depends:       base,
                        doctemplates,
                        doclayout >= 0.2 && < 0.3,
+                       containers,
                        aeson,
                        Glob,
                        tasty,
diff --git a/src/Text/DocTemplates.hs b/src/Text/DocTemplates.hs
--- a/src/Text/DocTemplates.hs
+++ b/src/Text/DocTemplates.hs
@@ -180,6 +180,7 @@
 -   If @variable@ is an array, the material inside the loop will be
     evaluated repeatedly, with @variable@ being set to each value of the
     array in turn, and concatenated.
+-   If @variable@ is a map, the material inside will be set to the map.
 -   If the value of the associated variable is not an array or a map, a
     single iteration will be performed on its value.
 
@@ -194,6 +195,10 @@
 > ${ for(foo.bar) }
 >   - ${ foo.bar.last }, ${ foo.bar.first }
 > ${ endfor }
+>
+> $for(mymap)$
+> $it.name$: $it.office$
+> $endfor$
 
 You may optionally specify a separator between consecutive values using
 @sep@ (enclosed in matched delimiters). The material between @sep@ and
@@ -317,9 +322,7 @@
 > $for(metadata/pairs)$
 > - $it.key$: $it.value$
 > $endfor$
-
-Filters may also be applied to the results of partials:
-
+>
 > $employee:name()/uppercase$
 
 Filters may be chained:
@@ -342,11 +345,9 @@
     @key@ and @value@ fields. If the original value was an array, the
     @key@ will be the array index, starting with 1.
 
--   @uppercase@: Converts a textual value to uppercase, and has no
-    effect on other values.
+-   @uppercase@: Converts text to uppercase.
 
--   @lowercase@: Converts a textual value to lowercase, and has no
-    effect on other values.
+-   @lowercase@: Converts text to lowercase.
 
 -   @length@: Returns the length of the value: number of characters for
     a textual value, number of elements for a map or array.
@@ -354,19 +355,19 @@
 -   @reverse@: Reverses a textual value or array, and has no effect on
     other values.
 
--   @chomp@: Removes trailing newlines (and breakable space) from a
-    textual value, and has no effect on other values.
+-   @chomp@: Removes trailing newlines (and breakable space).
 
--   @alpha@: Converts a textual value that can be read as an integer
-    into a lowercase alphabetic character @a..z@ (mod 26), and has no
-    effect on other values. This can be used to get lettered enumeration
-    from array indices. To get uppercase letters, chain with
-    @uppercase@.
+-   @nowrap@: Disables line wrapping on breakable spaces.
 
--   @roman@: Converts a textual value that can be read as an integer
-    into a lowercase roman numerial, and has no effect on other values.
-    This can be used to get lettered enumeration from array indices. To
-    get uppercase roman, chain with @uppercase@.
+-   @alpha@: Converts textual values that can be read as an integer into
+    lowercase alphabetic characters @a..z@ (mod 26). This can be used to
+    get lettered enumeration from array indices. To get uppercase
+    letters, chain with @uppercase@.
+
+-   @roman@: Converts textual values that can be read as an integer into
+    lowercase roman numerials. This can be used to get lettered
+    enumeration from array indices. To get uppercase roman, chain with
+    @uppercase@.
 
 -   @left n \"leftborder\" \"rightborder\"@: Renders a textual value in
     a block of width @n@, aligned to the left, with an optional left and
diff --git a/src/Text/DocTemplates/Internal.hs b/src/Text/DocTemplates/Internal.hs
--- a/src/Text/DocTemplates/Internal.hs
+++ b/src/Text/DocTemplates/Internal.hs
@@ -95,6 +95,7 @@
     | Chomp
     | ToAlpha
     | ToRoman
+    | NoWrap
     | Block Alignment Int Border
     deriving (Show, Read, Data, Typeable, Generic, Eq, Ord)
 
@@ -281,6 +282,18 @@
   toYAML (ListVal xs) = toYAML xs
   toYAML (SimpleVal d) = toYAML $ toText $ DL.render Nothing d
 
+mapDoc :: TemplateTarget a => (Doc a -> Doc a) -> Val a -> Val a
+mapDoc f val =
+  case val of
+    SimpleVal d        -> SimpleVal (f d)
+    MapVal (Context m) -> MapVal (Context $ M.map (mapDoc f) m)
+    ListVal xs         -> ListVal $ map (mapDoc f) xs
+    NullVal            -> NullVal
+
+mapText :: TemplateTarget a => (Text -> Text) -> Val a -> Val a
+mapText f val =
+  runIdentity (traverse (return . fromText . f . toText) val)
+
 applyFilter :: TemplateTarget a => Filter -> Val a -> Val a
 applyFilter ToLength val = SimpleVal $ fromString . show $ len
   where
@@ -289,16 +302,8 @@
            MapVal (Context m) -> M.size m
            ListVal xs         -> length xs
            NullVal            -> 0
-applyFilter ToUppercase val =
-  case val of
-    SimpleVal d -> SimpleVal . runIdentity $
-                    traverse (pure . fromText . T.toUpper . toText) d
-    _ -> val
-applyFilter ToLowercase val =
-  case val of
-    SimpleVal d -> SimpleVal . runIdentity $
-                    traverse (pure . fromText . T.toLower . toText) d
-    _ -> val
+applyFilter ToUppercase val = mapText T.toUpper val
+applyFilter ToLowercase val = mapText T.toLower val
 applyFilter ToPairs val =
   case val of
     MapVal (Context m) ->
@@ -312,30 +317,21 @@
                     , ("value", v) ]
 applyFilter Reverse val =
   case val of
-    SimpleVal d -> SimpleVal . runIdentity $
-                    traverse (pure . fromText . T.reverse . toText) d
     ListVal xs  -> ListVal (reverse xs)
-    _           -> val
-applyFilter Chomp val =
-  case val of
-    SimpleVal d -> SimpleVal $ DL.chomp d
-    _           -> val
-applyFilter ToAlpha val =
-  case val of
-    SimpleVal (DL.Text _ t) ->
-      case T.decimal (toText t) of
-        Right (y,"") -> SimpleVal $ fromString
-                         [chr (ord 'a' + (y `mod` 26) - 1)]
-        _            -> val
-    _           -> val
-applyFilter ToRoman val =
-  case val of
-    SimpleVal (DL.Text _ t) ->
-      case T.decimal (toText t) of
-        Right (y,"") -> maybe val (SimpleVal . DL.literal . fromText)
-                                  (toRoman y)
-        _            -> val
+    SimpleVal{} -> mapText T.reverse val
     _           -> val
+applyFilter Chomp val = mapDoc DL.chomp val
+applyFilter ToAlpha val = mapText toAlpha val
+  where toAlpha t =
+          case T.decimal t of
+            Right (y,"") -> fromString [chr (ord 'a' + (y `mod` 26) - 1)]
+            _            -> t
+applyFilter ToRoman val = mapText toRoman' val
+  where toRoman' t =
+         case T.decimal t of
+           Right (y,"") -> maybe t id (toRoman y)
+           _            -> t
+applyFilter NoWrap val = mapDoc DL.nowrap val
 applyFilter (Block align n border) val =
   let constructor = case align of
                       LeftAligned  -> DL.lblock
@@ -413,6 +409,8 @@
     NullVal     -> return mempty
     ListVal xs  -> mapM (\iterval -> f $
                     Context $ M.insert "it" iterval $ unContext ctx) xs
+    MapVal ctx' -> (:[]) <$> f
+                    (Context $ M.insert "it" (MapVal ctx') $ unContext ctx)
     val' -> (:[]) <$> f (Context $ M.insert "it" val' $ unContext ctx)
 
 type RenderState = S.State Int
diff --git a/src/Text/DocTemplates/Parser.hs b/src/Text/DocTemplates/Parser.hs
--- a/src/Text/DocTemplates/Parser.hs
+++ b/src/Text/DocTemplates/Parser.hs
@@ -416,6 +416,7 @@
     "roman"     -> return ToRoman
     "reverse"   -> return Reverse
     "chomp"     -> return Chomp
+    "nowrap"    -> return NoWrap
     "left"      -> Block LeftAligned <$> pBlockWidth <*> pBlockBorders
     "right"     -> Block RightAligned <$> pBlockWidth <*> pBlockBorders
     "center"    -> Block Centered <$> pBlockWidth <*> pBlockBorders
diff --git a/test/filters.test b/test/filters.test
--- a/test/filters.test
+++ b/test/filters.test
@@ -7,7 +7,10 @@
   "items": [ "one with\na line break",
             "two",
             "three with\na line break" ],
-  "hasblanks": "hello\n\n"
+  "hasblanks": "hello\n\n",
+  "hasblanksmap": { "a": "hello\n\n",
+                    "b": "there\n\n" },
+  "digits": [1, 5, 20]
 }
 .
 $bar/length$
@@ -16,6 +19,8 @@
 $bim/length$
 $sup/length$
 
+$baz/uppercase[, ]$
+
 $for(baz)$
 $it$
 $it/uppercase$
@@ -35,6 +40,16 @@
 $items/pairs/reverse:enum()$
 
 ($hasblanks/chomp$)
+
+$for(hasblanksmap/chomp/pairs/uppercase)$
+$it.key$ ($it.value$)
+$endfor$
+
+$digits/roman[ ]$
+
+$for(bim/uppercase)$
+$it.Zub$
+$endfor$
 .
 0
 2
@@ -42,6 +57,8 @@
 1
 2
 
+A, B
+
 a
 A
 a
@@ -65,3 +82,10 @@
 
 
 (hello)
+
+A (HELLO)
+B (THERE)
+
+i v xx
+
+SIM
diff --git a/test/keyval.txt b/test/keyval.txt
new file mode 100644
--- /dev/null
+++ b/test/keyval.txt
@@ -0,0 +1,1 @@
+
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -2,6 +2,8 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 
 import Text.DocLayout (render)
+import qualified Text.DocLayout as DL
+import qualified Data.Map as M
 import Text.DocTemplates
 import Test.Tasty.Golden
 import Test.Tasty
@@ -65,6 +67,19 @@
                    (renderTemplate t (object ["foo" .= ("42" :: T.Text)]))
                   Left e  -> T.pack e
       res @?= "not breakable and\nthis is\nbreakable\nok? 42"
+  , testCase "nowrap filter" $ do
+      (templ :: Either String (Template T.Text)) <-
+        compileTemplate "foo" "$foo/nowrap$\n$foo$"
+      let res :: T.Text
+          res = case templ of
+                  Right t -> render (Just 10)
+                   (renderTemplate t (Context $ M.insert "foo"
+                     (SimpleVal $
+                       DL.hsep ["hello", "this", "is", "a",
+                                "test", "of", "the", "wrapping"]
+                       :: Val T.Text) mempty))
+                  Left e  -> T.pack e
+      res @?= "hello this is a test of the wrapping\nhello this\nis a test\nof the\nwrapping"
   ]
 
 {- The test "golden" files are structured as follows:
