summaryrefslogtreecommitdiffstats
path: root/term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-06-12 19:05:47 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-06-12 19:05:47 +0000
commit9d72453df4dc511deb6dc6371e56a40f8fe3c0a8 (patch)
tree5caf35e06b9803aa07004c9ac9c7c3840dc50a36 /term.c
parentb393472ea460fc68b1f16089f9ce2375a7d78374 (diff)
downloadmandoc-9d72453df4dc511deb6dc6371e56a40f8fe3c0a8.tar.gz
Implement automatic line breaking
inside individual table cells that contain text blocks. This cures overlong lines in various Xenocara manuals.
Diffstat (limited to 'term.c')
-rw-r--r--term.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/term.c b/term.c
index 2e917c8f..bbadef66 100644
--- a/term.c
+++ b/term.c
@@ -40,6 +40,18 @@ static void endline(struct termp *);
void
+term_setcol(struct termp *p, size_t maxtcol)
+{
+ if (maxtcol > p->maxtcol) {
+ p->tcols = mandoc_recallocarray(p->tcols,
+ p->maxtcol, maxtcol, sizeof(*p->tcols));
+ p->maxtcol = maxtcol;
+ }
+ p->lasttcol = maxtcol - 1;
+ p->tcol = p->tcols;
+}
+
+void
term_free(struct termp *p)
{
for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++)
@@ -116,9 +128,9 @@ term_flushln(struct termp *p)
p->maxrmargin - p->viscol - vbl : 0;
vis = vend = 0;
- if (p->lasttcol == 0)
+ if ((p->flags && TERMP_MULTICOL) == 0)
p->tcol->col = 0;
- while (p->tcol->col < p->lastcol) {
+ while (p->tcol->col < p->tcol->lastcol) {
/*
* Handle literal tab characters: collapse all
@@ -126,7 +138,7 @@ term_flushln(struct termp *p)
*/
ntab = 0;
- while (p->tcol->col < p->lastcol &&
+ while (p->tcol->col < p->tcol->lastcol &&
p->tcol->buf[p->tcol->col] == '\t') {
vend = term_tab_next(vis);
vbl += vend - vis;
@@ -143,7 +155,7 @@ term_flushln(struct termp *p)
*/
jhy = 0;
- for (j = p->tcol->col; j < p->lastcol; j++) {
+ for (j = p->tcol->col; j < p->tcol->lastcol; j++) {
if (p->tcol->buf[j] == ' ' || p->tcol->buf[j] == '\t')
break;
@@ -178,7 +190,7 @@ term_flushln(struct termp *p)
if (vend > bp && jhy == 0 && vis > 0 &&
(p->flags & TERMP_BRNEVER) == 0) {
- if (p->lasttcol)
+ if (p->flags & TERMP_MULTICOL)
return;
endline(p);
@@ -206,14 +218,14 @@ term_flushln(struct termp *p)
* Write out the rest of the word.
*/
- for ( ; p->tcol->col < p->lastcol; p->tcol->col++) {
+ for ( ; p->tcol->col < p->tcol->lastcol; p->tcol->col++) {
if (vend > bp && jhy > 0 && p->tcol->col > jhy)
break;
if (p->tcol->buf[p->tcol->col] == '\t')
break;
if (p->tcol->buf[p->tcol->col] == ' ') {
j = p->tcol->col;
- while (p->tcol->col < p->lastcol &&
+ while (p->tcol->col < p->tcol->lastcol &&
p->tcol->buf[p->tcol->col] == ' ')
p->tcol->col++;
dv = (p->tcol->col - j) * (*p->width)(p, ' ');
@@ -260,10 +272,13 @@ term_flushln(struct termp *p)
else
vis = 0;
- p->col = p->lastcol = 0;
+ p->col = p->tcol->col = p->tcol->lastcol = 0;
p->minbl = p->trailspace;
p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
+ if (p->flags & TERMP_MULTICOL)
+ return;
+
/* Trailing whitespace is significant in some columns. */
if (vis && vbl && (TERMP_BRTRSP & p->flags))
@@ -305,7 +320,7 @@ term_newln(struct termp *p)
{
p->flags |= TERMP_NOSPACE;
- if (p->lastcol || p->viscol)
+ if (p->tcol->lastcol || p->viscol)
term_flushln(p);
}
@@ -565,12 +580,12 @@ term_word(struct termp *p, const char *word)
}
}
/* Trim trailing backspace/blank pair. */
- if (p->lastcol > 2 &&
- (p->tcol->buf[p->lastcol - 1] == ' ' ||
- p->tcol->buf[p->lastcol - 1] == '\t'))
- p->lastcol -= 2;
- if (p->col > p->lastcol)
- p->col = p->lastcol;
+ if (p->tcol->lastcol > 2 &&
+ (p->tcol->buf[p->tcol->lastcol - 1] == ' ' ||
+ p->tcol->buf[p->tcol->lastcol - 1] == '\t'))
+ p->tcol->lastcol -= 2;
+ if (p->col > p->tcol->lastcol)
+ p->col = p->tcol->lastcol;
continue;
default:
continue;
@@ -613,10 +628,10 @@ bufferc(struct termp *p, char c)
}
if (p->col + 1 >= p->tcol->maxcols)
adjbuf(p->tcol, p->col + 1);
- if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
+ if (p->tcol->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
p->tcol->buf[p->col] = c;
- if (p->lastcol < ++p->col)
- p->lastcol = p->col;
+ if (p->tcol->lastcol < ++p->col)
+ p->tcol->lastcol = p->col;
}
/*
@@ -659,10 +674,10 @@ encode1(struct termp *p, int c)
p->tcol->buf[p->col++] = c;
p->tcol->buf[p->col++] = '\b';
}
- if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
+ if (p->tcol->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
p->tcol->buf[p->col] = c;
- if (p->lastcol < ++p->col)
- p->lastcol = p->col;
+ if (p->tcol->lastcol < ++p->col)
+ p->tcol->lastcol = p->col;
if (p->flags & TERMP_BACKAFTER) {
p->flags |= TERMP_BACKBEFORE;
p->flags &= ~TERMP_BACKAFTER;
@@ -688,7 +703,7 @@ encode(struct termp *p, const char *word, size_t sz)
isgraph((unsigned char)word[i]))
encode1(p, word[i]);
else {
- if (p->lastcol <= p->col ||
+ if (p->tcol->lastcol <= p->col ||
(word[i] != ' ' && word[i] != ASCII_NBRSP))
p->tcol->buf[p->col] = word[i];
p->col++;
@@ -705,8 +720,8 @@ encode(struct termp *p, const char *word, size_t sz)
}
}
}
- if (p->lastcol < p->col)
- p->lastcol = p->col;
+ if (p->tcol->lastcol < p->col)
+ p->tcol->lastcol = p->col;
}
void