diff --git a/formatting.cabal b/formatting.cabal
--- a/formatting.cabal
+++ b/formatting.cabal
@@ -1,12 +1,12 @@
 name:                formatting
-version:             5.2
+version:             5.3
 synopsis:            Combinator-based type-safe formatting (like printf() or FORMAT)
 description:         Combinator-based type-safe formatting (like printf() or FORMAT), modelled from the HoleyMonoids package.
 license:             BSD3
 license-file:        LICENSE
-author:              Chris Done, Shachaf Ben-Kiki, Martijn van Steenbergen
+author:              Chris Done, Shachaf Ben-Kiki, Martijn van Steenbergen, Mike Meyer
 maintainer:          chrisdone@gmail.com
-copyright:           2013 Chris Done, Shachaf Ben-Kiki, Martijn van Steenbergen
+copyright:           2013 Chris Done, Shachaf Ben-Kiki, Martijn van Steenbergen, Mike Meyer
 category:            Text
 build-type:          Simple
 cabal-version:       >=1.8
diff --git a/src/Formatting/Formatters.hs b/src/Formatting/Formatters.hs
--- a/src/Formatting/Formatters.hs
+++ b/src/Formatting/Formatters.hs
@@ -32,12 +32,16 @@
   sci,
   scifmt,
   shortest,
+  groupInt,
   commas,
   ords,
   asInt,
   -- * Padding
   left,
   right,
+  center,
+  fitLeft,
+  fitRight,
   -- * Bases
   base,
   bin,
@@ -158,19 +162,48 @@
 right :: Buildable a => Int -> Char -> Format a
 right i c = later (T.right i c)
 
+-- | Pad the left & right hand side of a string until it reaches k characters
+-- wide, if necessary filling with character c.
+center :: Buildable a => Int -> Char -> Format a
+center i c = later centerT where
+  centerT = T.fromLazyText . LT.center (fromIntegral i) c . T.toLazyText . B.build
+
+-- | Group integral numbers, e.g. groupInt 2 '.' on 123456 -> \"12.34.56\".
+groupInt :: (Buildable n,Integral n) => Int -> Char -> Format n
+groupInt 0 _ = later B.build
+groupInt i c = later (commaize)
+  where commaize =
+          T.fromLazyText . LT.reverse .
+          foldr merge "" .
+          LT.zip (zeros <> cycle' zeros') .
+          LT.reverse .
+          T.toLazyText .
+          B.build
+        zeros =
+          LT.replicate (fromIntegral i)
+                       (LT.singleton '0')
+        zeros' = LT.singleton c <> LT.tail zeros
+        merge (f,c') rest
+          | f == c = LT.singleton c <> LT.singleton c' <> rest
+          | otherwise = LT.singleton c' <> rest
+        cycle' xs = xs <> cycle' xs
+
+-- | Fit in the given length, truncating on the left.
+fitLeft :: Buildable a => Int -> Format a
+fitLeft size = later (fit (fromIntegral size)) where
+  fit i = T.fromLazyText . LT.take i . T.toLazyText . B.build
+
+-- | Fit in the given length, truncating on the right.
+fitRight :: Buildable a => Int -> Format a
+fitRight size = later (fit (fromIntegral size)) where
+  fit i = T.fromLazyText .
+          (\t -> LT.drop (LT.length t - i) t)
+          . T.toLazyText
+          . B.build
+
 -- | Add commas to an integral, e.g 12000 -> \ "12,000".
 commas :: (Buildable n,Integral n) => Format n
-commas = later (commaize) where
-  commaize = T.fromLazyText .
-             LT.reverse .
-             foldr merge "" .
-             LT.zip ("000" <> cycle' ",00") .
-             LT.reverse .
-             T.toLazyText .
-             B.build
-  merge (f,c) rest | f == ',' = "," <> LT.singleton c <> rest
-                   | otherwise = LT.singleton c <> rest
-  cycle' xs = xs <> cycle' xs
+commas = groupInt 3 ','
 
 -- | Add a suffix to an integral, e.g. 1st, 2nd, 3rd, 21st.
 ords :: Integral n => Format n
@@ -189,7 +222,7 @@
 -- Bases
 base :: Integral a => Int -> Format a
 base numBase = later (B.build . atBase numBase)
-                
+
 -- | Render an integer using binary notation. (No leading 0b is
 -- added.) Defined as @bin = 'base' 2@.
 bin :: Integral a => Format a
@@ -203,7 +236,7 @@
 {-# INLINE oct #-}
 
 -- | Render an integer using hexadecimal notation. (No leading 0x is
--- added.) Has a specialized implementation. 
+-- added.) Has a specialized implementation.
 hex :: Integral a => Format a
 hex = later T.hex
 {-# INLINE hex #-}
