- for (sz = 0; *cp; cp++)
- sz += (*p->width)(p, *cp);
+ /*
+ * Account for escaped sequences within string length
+ * calculations. This follows the logic in term_word() as we
+ * must calculate the width of produced strings.
+ */
+
+ sz = 0;
+ while ('\0' != *cp)
+ switch (*cp) {
+ case ('\\'):
+ ++cp;
+ esc = mandoc_escape(&cp, &seq, &ssz);
+ if (ESCAPE_ERROR == esc)
+ return(sz);
+
+ switch (esc) {
+ case (ESCAPE_PREDEF):
+ rhs = chars_res2str
+ (p->symtab, seq, ssz, &rsz);
+ break;
+ case (ESCAPE_SPECIAL):
+ rhs = chars_spec2str
+ (p->symtab, seq, ssz, &rsz);
+
+ if (ssz != 1 || rhs)
+ break;
+
+ rhs = seq;
+ rsz = ssz;
+ break;
+ default:
+ rhs = NULL;
+ break;
+ }
+
+ if (NULL == rhs)
+ break;
+
+ for (i = 0; i < rsz; i++)
+ sz += (*p->width)(p, *rhs++);
+ break;
+ case (ASCII_NBRSP):
+ sz += (*p->width)(p, ' ');
+ cp++;
+ break;
+ case (ASCII_HYPH):
+ sz += (*p->width)(p, '-');
+ cp++;
+ break;
+ default:
+ sz += (*p->width)(p, *cp++);
+ break;
+ }