summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2022-08-15 13:01:41 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2022-08-15 13:01:41 +0000
commit8633c08815c552227792d2c1aeb4d55fe172cd9b (patch)
tree54d33757765333a76a75963a1bff6b0a3a7b8604
parente01b38f4fb637cc74ede0bc4a6b1b4e8aa7f5306 (diff)
In GNU, Heirloom, and Plan 9 roff, tab positions apply to *input* lines,
not to *output* lines. In particular, if an input line gets broken in fill mode and a tab occurs in the second output line, it advances to a position of at least (width of the first output line) + (width of a space character even though this is never printed) + (width of the part of the second output line that precedes the tab). Implement the same logic in mandoc. Again, do not use tabs in filled text: they have surprising effects, including this one.
-rw-r--r--usr.bin/mandoc/man_term.c3
-rw-r--r--usr.bin/mandoc/term.c19
-rw-r--r--usr.bin/mandoc/term.h3
3 files changed, 15 insertions, 10 deletions
diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c
index 2152cdea691..2433abcdbae 100644
--- a/usr.bin/mandoc/man_term.c
+++ b/usr.bin/mandoc/man_term.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: man_term.c,v 1.190 2022/04/27 17:04:15 schwarze Exp $ */
+/* $OpenBSD: man_term.c,v 1.191 2022/08/15 13:01:40 schwarze Exp $ */
/*
* Copyright (c) 2010-2015,2017-2020,2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -973,6 +973,7 @@ out:
! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
(n->next == NULL || n->next->flags & NODE_LINE)) {
p->flags |= TERMP_BRNEVER | TERMP_NOSPACE;
+ p->tcol->taboff = 0;
if (n->string != NULL && *n->string != '\0')
term_flushln(p);
else
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index b57296c45ce..fe098f76c0b 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: term.c,v 1.147 2022/08/15 10:21:01 schwarze Exp $ */
+/* $OpenBSD: term.c,v 1.148 2022/08/15 13:01:40 schwarze Exp $ */
/*
* Copyright (c) 2010-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -155,6 +155,7 @@ term_flushln(struct termp *p)
/* Finally, print the field content. */
term_field(p, vbl, nbr);
+ p->tcol->taboff += vbr + (*p->width)(p, ' ');
/*
* If there is no text left in the field, exit the loop.
@@ -307,7 +308,9 @@ term_fill(struct termp *p, size_t *nbr, size_t *vbr, size_t vtarget)
default:
switch (p->tcol->buf[ic]) {
case '\t':
+ vis += p->tcol->taboff;
vis = term_tab_next(vis);
+ vis -= p->tcol->taboff;
break;
case ASCII_NBRSP: /* Non-breakable space. */
p->tcol->buf[ic] = ' ';
@@ -346,8 +349,8 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
{
size_t ic; /* Character position in the input buffer. */
size_t vis; /* Visual position of the current character. */
+ size_t vt; /* Visual position including tab offset. */
size_t dv; /* Visual width of the current character. */
- size_t vn; /* Visual position of the next character. */
vis = 0;
for (ic = p->tcol->col; ic < nbr; ic++) {
@@ -362,13 +365,13 @@ term_field(struct termp *p, size_t vbl, size_t nbr)
case ASCII_BREAK:
continue;
case '\t':
- vn = term_tab_next(vis);
- vbl += vn - vis;
- vis = vn;
- continue;
case ' ':
case ASCII_NBRSP:
- dv = (*p->width)(p, ' ');
+ if (p->tcol->buf[ic] == '\t') {
+ vt = p->tcol->taboff + vis;
+ dv = term_tab_next(vt) - vt;
+ } else
+ dv = (*p->width)(p, ' ');
vbl += dv;
vis += dv;
continue;
@@ -430,7 +433,7 @@ endline(struct termp *p)
void
term_newln(struct termp *p)
{
-
+ p->tcol->taboff = 0;
p->flags |= TERMP_NOSPACE;
if (p->tcol->lastcol || p->viscol)
term_flushln(p);
diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h
index deba9352979..afdc5591f57 100644
--- a/usr.bin/mandoc/term.h
+++ b/usr.bin/mandoc/term.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: term.h,v 1.76 2021/10/04 18:56:24 schwarze Exp $ */
+/* $OpenBSD: term.h,v 1.77 2022/08/15 13:01:40 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017, 2019 Ingo Schwarze <schwarze@openbsd.org>
@@ -56,6 +56,7 @@ struct termp_col {
size_t col; /* Byte in buf to be written. */
size_t rmargin; /* Current right margin. */
size_t offset; /* Current left margin. */
+ size_t taboff; /* Offset for literal tabs. */
};
struct termp {