Implement spacing of columns as defined in the table layout;
authorschwarze <schwarze@openbsd.org>
Tue, 27 Jun 2017 18:23:29 +0000 (18:23 +0000)
committerschwarze <schwarze@openbsd.org>
Tue, 27 Jun 2017 18:23:29 +0000 (18:23 +0000)
this is for example used by lftp(1)
and, ironically, misused by our very own tbl(7) manual...

usr.bin/mandoc/out.c
usr.bin/mandoc/out.h
usr.bin/mandoc/tbl_layout.c
usr.bin/mandoc/tbl_term.c

index 0a6daf4..237c6f4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: out.c,v 1.41 2017/06/15 00:27:22 schwarze Exp $ */
+/*     $OpenBSD: out.c,v 1.42 2017/06/27 18:23:29 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -18,6 +18,7 @@
 #include <sys/types.h>
 
 #include <assert.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -138,8 +139,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
                        if (1 < spans)
                                continue;
                        icol = dp->layout->col;
-                       if (maxcol < icol)
-                               maxcol = icol;
+                       while (maxcol < icol)
+                               tbl->cols[++maxcol].spacing = SIZE_MAX;
                        col = tbl->cols + icol;
                        col->flags |= dp->layout->flags;
                        if (dp->layout->flags & TBL_CELL_WIGN)
@@ -152,6 +153,10 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
                                    (*tbl->sulen)(&su, tbl->arg);
                        if (col->width < dp->layout->width)
                                col->width = dp->layout->width;
+                       if (dp->layout->spacing != SIZE_MAX &&
+                           (col->spacing == SIZE_MAX ||
+                            col->spacing < dp->layout->spacing))
+                               col->spacing = dp->layout->spacing;
                        tblcalc_data(tbl, col, opts, dp,
                            dp->block == 0 ? 0 :
                            dp->layout->width ? dp->layout->width :
@@ -170,6 +175,8 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
        ewidth = xwidth = 0;
        for (icol = 0; icol <= maxcol; icol++) {
                col = tbl->cols + icol;
+               if (col->spacing == SIZE_MAX || icol == maxcol)
+                       col->spacing = 3;
                if (col->flags & TBL_CELL_EQUAL) {
                        necol++;
                        if (ewidth < col->width)
index a0170d9..8ba11ad 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: out.h,v 1.21 2017/06/12 20:14:03 schwarze Exp $ */
+/*     $OpenBSD: out.h,v 1.22 2017/06/27 18:23:29 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -33,6 +33,7 @@ enum  roffscale {
 struct roffcol {
        size_t           width; /* width of cell */
        size_t           decimal; /* decimal position in cell */
+       size_t           spacing; /* spacing after the column */
        int              flags; /* layout flags, see tbl_cell */
 };
 
index 3405095..e2d683b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tbl_layout.c,v 1.30 2017/06/13 16:11:58 schwarze Exp $ */
+/*     $OpenBSD: tbl_layout.c,v 1.31 2017/06/27 18:23:29 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2012, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -18,6 +18,7 @@
 #include <sys/types.h>
 
 #include <ctype.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -355,6 +356,7 @@ cell_alloc(struct tbl_node *tbl, struct tbl_row *rp, enum tbl_cellt pos)
        struct tbl_cell *p, *pp;
 
        p = mandoc_calloc(1, sizeof(*p));
+       p->spacing = SIZE_MAX;
        p->pos = pos;
 
        if ((pp = rp->last) != NULL) {
index 7466bfa..fbbebff 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tbl_term.c,v 1.42 2017/06/17 14:55:02 schwarze Exp $ */
+/*     $OpenBSD: tbl_term.c,v 1.43 2017/06/27 18:23:29 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -99,7 +99,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                for (ic = 0; ic < sp->opts->cols; ic++) {
                        coloff += tp->tbl.cols[ic].width;
                        term_tab_iset(coloff);
-                       coloff += 3;
+                       coloff += tp->tbl.cols[ic].spacing;
                }
 
                /* Center the table as a whole. */
@@ -108,9 +108,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                if (sp->opts->opts & TBL_OPT_CENTRE) {
                        tsz = sp->opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX)
                            ? 2 : !!sp->opts->lvert + !!sp->opts->rvert;
-                       for (ic = 0; ic < sp->opts->cols; ic++)
-                               tsz += tp->tbl.cols[ic].width + 3;
-                       tsz -= 3;
+                       for (ic = 0; ic + 1 < sp->opts->cols; ic++)
+                               tsz += tp->tbl.cols[ic].width +
+                                   tp->tbl.cols[ic].spacing;
+                       if (sp->opts->cols)
+                               tsz += tp->tbl.cols[sp->opts->cols - 1].width;
                        if (offset + tsz > tp->tcol->rmargin)
                                tsz -= 1;
                        tp->tcol->offset = offset + tp->tcol->rmargin > tsz ?
@@ -157,9 +159,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                        }
                        coloff += tp->tbl.cols[ic].width;
                        tp->tcol->rmargin = coloff;
-                       coloff++;
                        if (ic + 1 < sp->opts->cols)
-                               coloff += 2;
+                               coloff += tp->tbl.cols[ic].spacing;
                        if (spans) {
                                spans--;
                                continue;
@@ -173,7 +174,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                /* Set up a column for a right vertical frame. */
 
                tp->tcol++;
-               tp->tcol->offset = coloff;
+               tp->tcol->offset = coloff + 1;
                tp->tcol->rmargin = tp->maxrmargin;
 
                /* Spans may have reduced the number of columns. */
@@ -325,13 +326,13 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                                    tp->tcol + 1 == tp->tcols + tp->lasttcol))
                                        continue;
 
-                               if (tp->tcol->rmargin > tp->viscol) {
+                               if (tp->viscol < tp->tcol->rmargin) {
                                        (*tp->advance)(tp, tp->tcol->rmargin
                                           - tp->viscol);
                                        tp->viscol = tp->tcol->rmargin;
                                }
-
-                               if (tp->tcol->rmargin + 1 > tp->viscol) {
+                               while (tp->viscol < tp->tcol->rmargin +
+                                   tp->tbl.cols[ic].spacing / 2) {
                                        (*tp->letter)(tp, fc);
                                        tp->viscol++;
                                }
@@ -351,10 +352,11 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                                                break;
                                        }
                                }
-
-                               (*tp->letter)(tp,
-                                   fc == ' ' ? '|' : vert ? '+' : fc);
-                               tp->viscol++;
+                               if (tp->tbl.cols[ic].spacing) {
+                                       (*tp->letter)(tp, fc == ' ' ? '|' :
+                                           vert ? '+' : fc);
+                                       tp->viscol++;
+                               }
 
                                if (fc != ' ') {
                                        if (cp != NULL &&
@@ -366,7 +368,8 @@ term_tbl(struct termp *tp, const struct tbl_span *sp)
                                        else
                                                fc = ' ';
                                }
-                               if (vert > 1 || fc != ' ') {
+                               if (tp->tbl.cols[ic].spacing > 2 &&
+                                   (vert > 1 || fc != ' ')) {
                                        (*tp->letter)(tp, fc == ' ' ? '|' :
                                            vert > 1 ? '+' : fc);
                                        tp->viscol++;
@@ -446,6 +449,7 @@ static void
 tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
 {
        const struct tbl_cell *cp, *cpn, *cpp;
+       const struct roffcol *col;
        int      vert;
        char     line, cross;
 
@@ -462,7 +466,8 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
        if (cpn == cp)
                cpn = NULL;
        for (;;) {
-               tbl_char(tp, line, tp->tbl.cols[cp->col].width + 1);
+               col = tp->tbl.cols + cp->col;
+               tbl_char(tp, line, col->width + col->spacing / 2);
                vert = cp->vert;
                if ((cp = cp->next) == NULL)
                         break;
@@ -478,10 +483,12 @@ tbl_hrule(struct termp *tp, const struct tbl_span *sp, int kind)
                }
                if (sp->opts->opts & TBL_OPT_ALLBOX && !vert)
                        vert = 1;
-               if (vert)
-                       tbl_char(tp, cross, vert);
-               if (vert < 2)
-                       tbl_char(tp, line, 2 - vert);
+               if (col->spacing)
+                       tbl_char(tp, vert ? cross : line, 1);
+               if (col->spacing > 2)
+                       tbl_char(tp, vert > 1 ? cross : line, 1);
+               if (col->spacing > 4)
+                       tbl_char(tp, line, (col->spacing - 3) / 2);
        }
        if (kind) {
                term_word(tp, "+");