diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-09-15 14:36:16 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2010-09-15 14:36:16 +0000 |
commit | d314ff3f89a95ea238e50cfcbb6a6fc3848c56d2 (patch) | |
tree | 4d46e52e2868bfea5dec3c6f38ef479898448a47 /term.c | |
parent | ea02c27746628977c16bd9f8665b1ceed267c88f (diff) | |
download | mandoc-d314ff3f89a95ea238e50cfcbb6a6fc3848c56d2.tar.gz |
Allow string lengths to account for escapes. Now all calls to calculate
column width in -Tascii, -Tpdf, and -Tps will account for "more real"
string lengths.
Example:
.Bl -tag -width \s[+123424]foo
.It bar
baz
.El
The size escape will be correctly tossed.
.Bl -tag -width \(aqbar
.It \(aqbar
baz
.El
The \(aq will be correctly handled.
Diffstat (limited to 'term.c')
-rw-r--r-- | term.c | 48 |
1 files changed, 42 insertions, 6 deletions
@@ -458,7 +458,6 @@ void term_word(struct termp *p, const char *word) { const char *sv, *seq; - int sz; size_t ssz; enum roffdeco deco; @@ -515,7 +514,7 @@ term_word(struct termp *p, const char *word) continue; seq = ++word; - sz = a2roffdeco(&deco, &seq, &ssz); + word += a2roffdeco(&deco, &seq, &ssz); switch (deco) { case (DECO_RESERVED): @@ -542,7 +541,6 @@ term_word(struct termp *p, const char *word) break; } - word += sz; if (DECO_NOSPACE == deco && '\0' == *word) p->flags |= TERMP_NOSPACE; } @@ -645,10 +643,48 @@ term_len(const struct termp *p, size_t sz) size_t term_strlen(const struct termp *p, const char *cp) { - size_t sz; + size_t sz, ssz, rsz, i; + enum roffdeco d; + const char *seq, *rhs; - for (sz = 0; *cp; cp++) - sz += (*p->width)(p, *cp); + for (sz = 0; '\0' != *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. + */ + if ('\\' == *cp) { + seq = ++cp; + cp += a2roffdeco(&d, &seq, &ssz); + + switch (d) { + case (DECO_RESERVED): + rhs = chars_res2str + (p->symtab, seq, ssz, &rsz); + break; + case (DECO_SPECIAL): + /* FALLTHROUGH */ + case (DECO_SSPECIAL): + rhs = chars_spec2str + (p->symtab, seq, ssz, &rsz); + + /* Allow for one-char escapes. */ + if (DECO_SSPECIAL != d || rhs) + break; + + rhs = seq; + rsz = ssz; + break; + default: + rhs = NULL; + break; + } + + if (rhs) + for (i = 0; i < rsz; i++) + sz += (*p->width)(p, *rhs++); + } else + sz += (*p->width)(p, *cp++); return(sz); } |