From: schwarze Date: Thu, 8 Jun 2017 18:11:15 +0000 (+0000) Subject: Implement w layout specifier (minimum column width). X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=2c3e66c426702142f6874d869c4af553cb7036ae;p=openbsd Implement w layout specifier (minimum column width). Improve width calculation of text blocks. Reduces the groff/mandoc diff in Base+Xenocara by about 800 lines. --- diff --git a/regress/usr.bin/mandoc/tbl/mod/Makefile b/regress/usr.bin/mandoc/tbl/mod/Makefile index ab087b1e64c..df1e8f4787b 100644 --- a/regress/usr.bin/mandoc/tbl/mod/Makefile +++ b/regress/usr.bin/mandoc/tbl/mod/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.3 2017/05/01 20:53:58 schwarze Exp $ +# $OpenBSD: Makefile,v 1.4 2017/06/08 18:11:15 schwarze Exp $ -REGRESS_TARGETS = badfont expand expand-toowide font misalign +REGRESS_TARGETS = badfont expand expand-toowide font misalign width LINT_TARGETS = badfont font # groff-1.22.3 defects: diff --git a/regress/usr.bin/mandoc/tbl/mod/width.in b/regress/usr.bin/mandoc/tbl/mod/width.in new file mode 100644 index 00000000000..702dd19e77e --- /dev/null +++ b/regress/usr.bin/mandoc/tbl/mod/width.in @@ -0,0 +1,14 @@ +.TH TBL-MOD-WIDTH 1 "June 8, 2017" OpenBSD +.SH NAME +tbl-mod-width \- width modifier in table layout +.SH DESCRIPTION +normal text +.TS +box tab(:); +lw2 | lw(2n) | lw(0.2i) | lw2 . +a:abcd:T{ +a +T}:T{ +.SM abcd +T} +.TE diff --git a/regress/usr.bin/mandoc/tbl/mod/width.out_ascii b/regress/usr.bin/mandoc/tbl/mod/width.out_ascii new file mode 100644 index 00000000000..8ff6bf197ab --- /dev/null +++ b/regress/usr.bin/mandoc/tbl/mod/width.out_ascii @@ -0,0 +1,16 @@ +TBL-MOD-WIDTH(1) General Commands Manual TBL-MOD-WIDTH(1) + + + +NNAAMMEE + tbl-mod-width - width modifier in table layout + +DDEESSCCRRIIPPTTIIOONN + normal text + + +---+------+----+------+ + |a | abcd | a | abcd | + +---+------+----+------+ + + +OpenBSD June 8, 2017 TBL-MOD-WIDTH(1) diff --git a/share/man/man7/tbl.7 b/share/man/man7/tbl.7 index e50375eb936..84fd983f7fe 100644 --- a/share/man/man7/tbl.7 +++ b/share/man/man7/tbl.7 @@ -1,7 +1,7 @@ -.\" $OpenBSD: tbl.7,v 1.14 2015/01/29 00:33:14 schwarze Exp $ +.\" $OpenBSD: tbl.7,v 1.15 2017/06/08 18:11:15 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons -.\" Copyright (c) 2014, 2015 Ingo Schwarze +.\" Copyright (c) 2014, 2015, 2017 Ingo Schwarze .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 29 2015 $ +.Dd $Mdocdate: June 8 2017 $ .Dt TBL 7 .Os .Sh NAME @@ -245,7 +245,7 @@ Emit a double-vertical bar instead of data. .Pp Keys may be followed by a set of modifiers. A modifier is either a modifier key or a natural number for specifying -the minimum width of a column. +the spacing to the right of the column. The following case-insensitive modifier keys are available: .Bl -tag -width 2n .It Cm b @@ -284,8 +284,7 @@ Currently ignored. Move cell content up by half a table line. Currently ignored. .It Cm w -Specify minimum column width. -Currently ignored. +Specify the minimum column width. .It Cm x After determining the width of all other columns, distribute the rest of the line length among all columns having the @@ -300,7 +299,7 @@ minimum width 10, followed by vertical bar, followed by a left-justified column of minimum width 10, another vertical bar, then a column using bold font justified about the decimal point in numbers: .Pp -.Dl c10 | l10 | nfB +.Dl cw10 | lw10 | nfB .Ss Data The data section follows the last layout row. By default, cells in a data section are delimited by a tab. diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index a0c44e1cf85..d9860bf0dc3 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.167 2017/06/08 00:21:23 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.168 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -246,9 +246,10 @@ enum tbl_cellt { */ struct tbl_cell { struct tbl_cell *next; + char *wstr; /* min width represented as a string */ + size_t width; /* minimum column width */ + size_t spacing; /* to the right of the column */ int vert; /* width of subsequent vertical line */ - enum tbl_cellt pos; - size_t spacing; int col; /* column number, starting from 0 */ int flags; #define TBL_CELL_TALIGN (1 << 0) /* t, T */ @@ -259,6 +260,7 @@ struct tbl_cell { #define TBL_CELL_UP (1 << 5) /* u, U */ #define TBL_CELL_WIGN (1 << 6) /* z, Z */ #define TBL_CELL_WMAX (1 << 7) /* x, X */ + enum tbl_cellt pos; }; /* @@ -286,9 +288,10 @@ enum tbl_datt { */ struct tbl_dat { struct tbl_cell *layout; /* layout cell */ - int spans; /* how many spans follow */ struct tbl_dat *next; char *string; /* data (NULL if not TBL_DATA_DATA) */ + int spans; /* how many spans follow */ + int block; /* T{ text block T} */ enum tbl_datt pos; }; diff --git a/usr.bin/mandoc/out.c b/usr.bin/mandoc/out.c index 9cf5c97c4dd..e9d6e873843 100644 --- a/usr.bin/mandoc/out.c +++ b/usr.bin/mandoc/out.c @@ -1,4 +1,4 @@ -/* $OpenBSD: out.c,v 1.36 2017/06/08 12:54:40 schwarze Exp $ */ +/* $OpenBSD: out.c,v 1.37 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze @@ -27,9 +27,10 @@ #include "out.h" static void tblcalc_data(struct rofftbl *, struct roffcol *, - const struct tbl_opts *, const struct tbl_dat *); + const struct tbl_opts *, const struct tbl_dat *, + size_t); static void tblcalc_literal(struct rofftbl *, struct roffcol *, - const struct tbl_dat *); + const struct tbl_dat *, size_t); static void tblcalc_number(struct rofftbl *, struct roffcol *, const struct tbl_opts *, const struct tbl_dat *); @@ -104,6 +105,7 @@ void tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, size_t totalwidth) { + struct roffsu su; const struct tbl_opts *opts; const struct tbl_dat *dp; struct roffcol *col; @@ -144,7 +146,16 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, col->flags |= dp->layout->flags; if (dp->layout->flags & TBL_CELL_WIGN) continue; - tblcalc_data(tbl, col, opts, dp); + if (dp->layout->wstr != NULL && + dp->layout->width == 0 && + a2roffsu(dp->layout->wstr, &su, SCALE_EN) + != NULL) + dp->layout->width = + (*tbl->sulen)(&su, tbl->arg); + if (col->width < dp->layout->width) + col->width = dp->layout->width; + tblcalc_data(tbl, col, opts, dp, dp->block ? + totalwidth / (sp->opts->cols + 1) : 0); } } @@ -232,7 +243,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, static void tblcalc_data(struct rofftbl *tbl, struct roffcol *col, - const struct tbl_opts *opts, const struct tbl_dat *dp) + const struct tbl_opts *opts, const struct tbl_dat *dp, size_t mw) { size_t sz; @@ -249,7 +260,7 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col, case TBL_CELL_CENTRE: case TBL_CELL_LEFT: case TBL_CELL_RIGHT: - tblcalc_literal(tbl, col, dp); + tblcalc_literal(tbl, col, dp, mw); break; case TBL_CELL_NUMBER: tblcalc_number(tbl, col, opts, dp); @@ -263,16 +274,29 @@ tblcalc_data(struct rofftbl *tbl, struct roffcol *col, static void tblcalc_literal(struct rofftbl *tbl, struct roffcol *col, - const struct tbl_dat *dp) + const struct tbl_dat *dp, size_t mw) { - size_t sz; - const char *str; - - str = dp->string ? dp->string : ""; - sz = (*tbl->slen)(str, tbl->arg); - - if (col->width < sz) - col->width = sz; + const char *str; /* Beginning of the first line. */ + const char *beg; /* Beginning of the current line. */ + char *end; /* End of the current line. */ + size_t sz; /* Length of the current line. */ + + if (dp->string == NULL || *dp->string == '\0') + return; + str = mw ? mandoc_strdup(dp->string) : dp->string; + for (beg = str; beg != NULL && *beg != '\0'; beg = end) { + end = mw ? strchr(beg, ' ') : NULL; + if (end != NULL) { + *end++ = '\0'; + while (*end == ' ') + end++; + } + sz = (*tbl->slen)(beg, tbl->arg); + if (col->width < sz) + col->width = sz; + } + if (mw) + free((void *)str); } static void diff --git a/usr.bin/mandoc/out.h b/usr.bin/mandoc/out.h index 4856dfbd08a..7e93f1c0700 100644 --- a/usr.bin/mandoc/out.h +++ b/usr.bin/mandoc/out.h @@ -1,4 +1,4 @@ -/* $OpenBSD: out.h,v 1.19 2017/06/08 12:54:40 schwarze Exp $ */ +/* $OpenBSD: out.h,v 1.20 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014, 2017 Ingo Schwarze @@ -41,14 +41,16 @@ struct roffsu { double scale; }; +typedef size_t (*tbl_sulen)(const struct roffsu *, void *); typedef size_t (*tbl_strlen)(const char *, void *); typedef size_t (*tbl_len)(size_t, void *); struct rofftbl { + tbl_sulen sulen; /* calculate scaling unit length */ tbl_strlen slen; /* calculate string length */ tbl_len len; /* produce width of empty space */ struct roffcol *cols; /* master column specifiers */ - void *arg; /* passed to slen and len */ + void *arg; /* passed to sulen, slen, and len */ }; #define SCALE_VS_INIT(p, v) \ diff --git a/usr.bin/mandoc/tbl.c b/usr.bin/mandoc/tbl.c index 0e638a482f2..63e91b77a50 100644 --- a/usr.bin/mandoc/tbl.c +++ b/usr.bin/mandoc/tbl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tbl.c,v 1.21 2015/10/06 18:30:44 schwarze Exp $ */ +/* $OpenBSD: tbl.c,v 1.22 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011, 2015 Ingo Schwarze @@ -112,6 +112,7 @@ tbl_free(struct tbl_node *tbl) while (rp->first != NULL) { cp = rp->first; rp->first = cp->next; + free(cp->wstr); free(cp); } free(rp); diff --git a/usr.bin/mandoc/tbl_data.c b/usr.bin/mandoc/tbl_data.c index 479d892855f..5d87e23a0f9 100644 --- a/usr.bin/mandoc/tbl_data.c +++ b/usr.bin/mandoc/tbl_data.c @@ -1,7 +1,7 @@ -/* $OpenBSD: tbl_data.c,v 1.28 2015/10/06 18:30:44 schwarze Exp $ */ +/* $OpenBSD: tbl_data.c,v 1.29 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2011, 2015 Ingo Schwarze + * Copyright (c) 2011, 2015, 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -142,6 +142,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, const char *p, int pos) } dat->pos = TBL_DATA_DATA; + dat->block = 1; if (dat->string != NULL) { sz = strlen(p + pos) + strlen(dat->string) + 2; diff --git a/usr.bin/mandoc/tbl_html.c b/usr.bin/mandoc/tbl_html.c index 38515498c25..c839d510ef9 100644 --- a/usr.bin/mandoc/tbl_html.c +++ b/usr.bin/mandoc/tbl_html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tbl_html.c,v 1.15 2017/02/05 18:13:28 schwarze Exp $ */ +/* $OpenBSD: tbl_html.c,v 1.16 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -29,22 +29,48 @@ static void html_tblopen(struct html *, const struct tbl_span *); static size_t html_tbl_len(size_t, void *); static size_t html_tbl_strlen(const char *, void *); +static size_t html_tbl_sulen(const struct roffsu *, void *); static size_t html_tbl_len(size_t sz, void *arg) { - return sz; } static size_t html_tbl_strlen(const char *p, void *arg) { - return strlen(p); } +static size_t +html_tbl_sulen(const struct roffsu *su, void *arg) +{ + switch (su->unit) { + case SCALE_FS: /* 2^16 basic units */ + return su->scale * 65536.0 / 24.0; + case SCALE_IN: /* 10 characters per inch */ + return su->scale * 10.0; + case SCALE_CM: /* 2.54 cm per inch */ + return su->scale * 10.0 / 2.54; + case SCALE_PC: /* 6 pica per inch */ + case SCALE_VS: + return su->scale * 10.0 / 6.0; + case SCALE_EN: + case SCALE_EM: + return su->scale; + case SCALE_PT: /* 12 points per pica */ + return su->scale * 10.0 / 6.0 / 12.0; + case SCALE_BU: /* 24 basic units per character */ + return su->scale / 24.0; + case SCALE_MM: /* 1/1000 inch */ + return su->scale / 100.0; + default: + abort(); + } +} + static void html_tblopen(struct html *h, const struct tbl_span *sp) { @@ -54,6 +80,7 @@ html_tblopen(struct html *h, const struct tbl_span *sp) if (h->tbl.cols == NULL) { h->tbl.len = html_tbl_len; h->tbl.slen = html_tbl_strlen; + h->tbl.sulen = html_tbl_sulen; tblcalc(&h->tbl, sp, 0); } diff --git a/usr.bin/mandoc/tbl_layout.c b/usr.bin/mandoc/tbl_layout.c index 57f21e6bc7e..b3b1cfad1ab 100644 --- a/usr.bin/mandoc/tbl_layout.c +++ b/usr.bin/mandoc/tbl_layout.c @@ -1,7 +1,7 @@ -/* $OpenBSD: tbl_layout.c,v 1.28 2015/10/12 00:07:27 schwarze Exp $ */ +/* $OpenBSD: tbl_layout.c,v 1.29 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons - * Copyright (c) 2012, 2014, 2015 Ingo Schwarze + * Copyright (c) 2012, 2014, 2015, 2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -60,6 +60,7 @@ mods(struct tbl_node *tbl, struct tbl_cell *cp, int ln, const char *p, int *pos) { char *endptr; + size_t sz; mod: while (p[*pos] == ' ' || p[*pos] == '\t') @@ -125,7 +126,22 @@ mod: case 'u': cp->flags |= TBL_CELL_UP; goto mod; - case 'w': /* XXX for now, ignore minimal column width */ + case 'w': + sz = 0; + if (p[*pos] == '(') { + (*pos)++; + while (p[*pos + sz] != '\0' && p[*pos + sz] != ')') + sz++; + } else + while (isdigit((unsigned char)p[*pos + sz])) + sz++; + if (sz) { + free(cp->wstr); + cp->wstr = mandoc_strndup(p + *pos, sz); + *pos += sz; + if (p[*pos] == ')') + (*pos)++; + } goto mod; case 'x': cp->flags |= TBL_CELL_WMAX; diff --git a/usr.bin/mandoc/tbl_term.c b/usr.bin/mandoc/tbl_term.c index 7e459046509..1bb94b77209 100644 --- a/usr.bin/mandoc/tbl_term.c +++ b/usr.bin/mandoc/tbl_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tbl_term.c,v 1.33 2017/06/07 17:38:08 schwarze Exp $ */ +/* $OpenBSD: tbl_term.c,v 1.34 2017/06/08 18:11:15 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons * Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze @@ -28,6 +28,7 @@ static size_t term_tbl_len(size_t, void *); static size_t term_tbl_strlen(const char *, void *); +static size_t term_tbl_sulen(const struct roffsu *, void *); static void tbl_char(struct termp *, char, size_t); static void tbl_data(struct termp *, const struct tbl_opts *, const struct tbl_dat *, @@ -42,16 +43,20 @@ static void tbl_word(struct termp *, const struct tbl_dat *); static size_t -term_tbl_strlen(const char *p, void *arg) +term_tbl_sulen(const struct roffsu *su, void *arg) { + return term_hspan((const struct termp *)arg, su) / 24; +} +static size_t +term_tbl_strlen(const char *p, void *arg) +{ return term_strlen((const struct termp *)arg, p); } static size_t term_tbl_len(size_t sz, void *arg) { - return term_len((const struct termp *)arg, sz); } @@ -76,6 +81,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) if (tp->tbl.cols == NULL) { tp->tbl.len = term_tbl_len; tp->tbl.slen = term_tbl_strlen; + tp->tbl.sulen = term_tbl_sulen; tp->tbl.arg = tp; tblcalc(&tp->tbl, sp, tp->tcol->rmargin - tp->tcol->offset);