diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
 # doclayout
 
+[![CI
+tests](https://github.com/jgm/doclayout/workflows/CI%20tests/badge.svg)](https://github.com/jgm/doclayout/actions)
+
 This is a prettyprinting library designed for laying out
 plain-text documents.  It originated in the pandoc module
 Text.Pandoc.Pretty, and its development has been guided by
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,14 @@
 # doclayout
 
+## 0.2.0.1
+
+  * Made `realLength` smarter about combining characters.
+    If a string starts with a combining character, that character
+    takes up a width of 1; if the combining character occurs after
+    another character, it takes 0.  See jgm/pandoc#5863.
+  * Improve `isBlank`, re-use in rendering code `for BreakingSpace`.
+  * Fixed incorrect `Text` width in renderig blocks.
+
 ## 0.2
 
   * Add instances for `Doc`: `Data`, `Typeable`, `Ord`, `Read`, `Generic`.
diff --git a/doclayout.cabal b/doclayout.cabal
--- a/doclayout.cabal
+++ b/doclayout.cabal
@@ -1,5 +1,5 @@
 name:                doclayout
-version:             0.2
+version:             0.2.0.1
 synopsis:            A prettyprinting library for laying out text documents.
 description:         doclayout is a prettyprinting library for laying out
                      text documents, with several features not present
diff --git a/src/Text/DocLayout.hs b/src/Text/DocLayout.hs
--- a/src/Text/DocLayout.hs
+++ b/src/Text/DocLayout.hs
@@ -80,7 +80,7 @@
 import Control.Monad.State.Strict
 import GHC.Generics
 import Data.Char (isSpace)
-import Data.List (intersperse, foldl')
+import Data.List (intersperse)
 import Data.Data (Data, Typeable)
 import Data.String
 import qualified Data.Text as T
@@ -366,9 +366,9 @@
 
 renderList (BeforeNonBlank d : xs) =
   case xs of
-    (x:_) | isBlank x -> renderList xs
-          | otherwise -> renderDoc d >> renderList xs
-    []                -> renderList xs
+    (x:_) | startsBlank x -> renderList xs
+          | otherwise     -> renderDoc d >> renderList xs
+    []                    -> renderList xs
 renderList (BlankLines num : xs) = do
   st <- get
   case output st of
@@ -389,16 +389,12 @@
   renderList xs
 
 renderList (BreakingSpace : xs) = do
-  let isText (Text _ _)     = True
-      isText (Block _ _)    = True
-      isText (AfterBreak _) = True
-      isText _              = False
   let isBreakingSpace BreakingSpace = True
-      isBreakingSpace _             = False
+      isBreakingSpace _ = False
   let xs' = dropWhile isBreakingSpace xs
-  let next = takeWhile isText xs'
+  let next = takeWhile (not . isBlank) xs'
   st <- get
-  let off = foldl' (+) 0 $ map offsetOf next
+  let off = foldr ((+) . offsetOf) 0 next
   case lineLength st of
         Just l | column st + 1 + off > l -> newline
         _  -> when (column st > 0) $ outp 1 " "
@@ -426,22 +422,34 @@
   case column st - realLength oldPref of
         n | n > 0 -> modify $ \s -> s{ prefix = oldPref <> T.replicate n " " }
         _ -> return ()
-  renderList $ intersperse CarriageReturn (map (Text 0) lns')
+  renderList $ intersperse CarriageReturn (map literal lns')
   modify $ \s -> s{ prefix = oldPref }
   renderList rest
 
 renderList (x:_) = error $ "renderList encountered " ++ show x
 
 isBlank :: HasChars a => Doc a -> Bool
-isBlank BreakingSpace  = True
-isBlank CarriageReturn = True
-isBlank NewLine        = True
-isBlank (BlankLines _) = True
-isBlank (Text _ t)     = foldrChar
-                             (\c _ -> if isSpace c then True else False)
-                             False t
-isBlank _              = False
+isBlank (Text _ t)         = isAllSpace t
+isBlank (Block _ ls)       = all isAllSpace ls
+isBlank (VFill _ t)        = isAllSpace t
+isBlank (Prefixed _ x)     = isBlank x
+isBlank (BeforeNonBlank x) = isBlank x
+isBlank (Flush x)          = isBlank x
+isBlank BreakingSpace      = True
+isBlank (AfterBreak t)     = isAllSpace t
+isBlank CarriageReturn     = True
+isBlank NewLine            = True
+isBlank (BlankLines _)     = True
+isBlank (Concat x y)       = isBlank x && isBlank y
+isBlank Empty              = True
 
+startsBlank :: HasChars a => Doc a -> Bool
+startsBlank (Text _ t) = foldrChar (const . isSpace) False t
+startsBlank x          = isBlank x
+
+isAllSpace :: HasChars a => a -> Bool
+isAllSpace = foldrChar ((&&) . isSpace) False
+
 isBlock :: Doc a -> Bool
 isBlock Block{} = True
 isBlock VFill{} = True
@@ -695,5 +703,13 @@
 -- | Get real length of string, taking into account combining and double-wide
 -- characters.
 realLength :: HasChars a => a -> Int
-realLength = foldrChar (\c tot -> tot + charWidth c) 0
+realLength s = case foldrChar go (0, False) s of
+                 (n, True)  -> n + 1 -- first char is combining char
+                      -- which we counted as 0 but really takes space
+                 (n, False) -> n
+  where
+   go c (tot, _combiningChar) =
+     case charWidth c of
+       0 -> (tot, True)
+       n -> (tot + n, False)
 
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -263,4 +263,9 @@
       (vfill "| " <> cblock 5 ("a" $$ "bbb") <> vfill " | " <>
           lblock 2 ("dd" $$ "ee" $$ "ff") <> vfill " |")
       "|   a   | dd |\n|  bbb  | ee |\n|       | ff |"
+
+  , renderTest "combining character at start"
+      Nothing
+      (text "\870" <> space <> text "a")
+      "\870 a"
   ]
