diff options
-rw-r--r-- | mandoc.h | 1 | ||||
-rw-r--r-- | out.c | 74 | ||||
-rw-r--r-- | out.h | 4 | ||||
-rw-r--r-- | tbl.7 | 16 | ||||
-rw-r--r-- | tbl_html.c | 2 | ||||
-rw-r--r-- | tbl_layout.c | 3 | ||||
-rw-r--r-- | tbl_term.c | 2 |
7 files changed, 91 insertions, 11 deletions
@@ -246,6 +246,7 @@ struct tbl_cell { #define TBL_CELL_EQUAL (1 << 4) /* e, E */ #define TBL_CELL_UP (1 << 5) /* u, U */ #define TBL_CELL_WIGN (1 << 6) /* z, Z */ +#define TBL_CELL_WMAX (1 << 7) /* x, X */ struct tbl_head *head; }; @@ -1,7 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -139,11 +139,14 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def) * used for the actual width calculations. */ void -tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) +tblcalc(struct rofftbl *tbl, const struct tbl_span *sp, + size_t totalwidth) { const struct tbl_dat *dp; struct roffcol *col; + size_t ewidth, xwidth; int spans; + int icol, maxcol, necol, nxcol; /* * Allocate the master column specifiers. These will hold the @@ -155,7 +158,7 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) tbl->cols = mandoc_calloc((size_t)sp->opts->cols, sizeof(struct roffcol)); - for ( ; sp; sp = sp->next) { + for (maxcol = 0; sp; sp = sp->next) { if (TBL_SPAN_DATA != sp->pos) continue; spans = 1; @@ -170,11 +173,72 @@ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp) spans = dp->spans; if (1 < spans) continue; - assert(dp->layout); - col = &tbl->cols[dp->layout->head->ident]; + icol = dp->layout->head->ident; + if (maxcol < icol) + maxcol = icol; + col = tbl->cols + icol; + col->flags |= dp->layout->flags; + if (dp->layout->flags & TBL_CELL_WIGN) + continue; tblcalc_data(tbl, col, sp->opts, dp); } } + + /* + * Count columns to equalize and columns to maximize. + * Find maximum width of the columns to equalize. + * Find total width of the columns *not* to maximize. + */ + + necol = nxcol = 0; + ewidth = xwidth = 0; + for (icol = 0; icol <= maxcol; icol++) { + col = tbl->cols + icol; + if (col->flags & TBL_CELL_EQUAL) { + necol++; + if (ewidth < col->width) + ewidth = col->width; + } + if (col->flags & TBL_CELL_WMAX) + nxcol++; + else + xwidth += col->width; + } + + /* + * Equalize columns, if requested for any of them. + * Update total width of the columns not to maximize. + */ + + if (necol) { + for (icol = 0; icol <= maxcol; icol++) { + col = tbl->cols + icol; + if ( ! (col->flags & TBL_CELL_EQUAL)) + continue; + if (col->width == ewidth) + continue; + if (nxcol && totalwidth) + xwidth += ewidth - col->width; + col->width = ewidth; + } + } + + /* + * If there are any columns to maximize, find the total + * available width, deducting 3n margins between columns. + * Distribute the available width evenly. + */ + + if (nxcol && totalwidth) { + xwidth = totalwidth - 3*maxcol - xwidth; + for (icol = 0; icol <= maxcol; icol++) { + col = tbl->cols + icol; + if ( ! (col->flags & TBL_CELL_WMAX)) + continue; + col->width = xwidth / nxcol--; + xwidth -= col->width; + } + } } static void @@ -34,6 +34,7 @@ enum roffscale { struct roffcol { size_t width; /* width of cell */ size_t decimal; /* decimal position in cell */ + int flags; /* layout flags, see tbl_cell */ }; struct roffsu { @@ -64,7 +65,8 @@ __BEGIN_DECLS while (/* CONSTCOND */ 0) int a2roffsu(const char *, struct roffsu *, enum roffscale); -void tblcalc(struct rofftbl *tbl, const struct tbl_span *); +void tblcalc(struct rofftbl *tbl, + const struct tbl_span *, size_t); __END_DECLS @@ -248,6 +248,11 @@ The following case-insensitive modifier keys are available: .Bl -tag -width 2n .It Cm b Use a bold font for the contents of this column. +.It Cm e +Make this column wider to match the maximum width +of any other column also having the +.Cm e +modifier. .It Cm f The next character selects the font to use for this column. See the @@ -255,16 +260,21 @@ See the manual for supported one-character font names. .It Cm i Use an italic font for the contents of this column. +.It Cm x +After determining the width of all other columns, distribute the +rest of the line length among all columns having the +.Cm x +modifier. +.It Cm z +Do not use this cell for determining the width of this column. .El .Pp The modifiers .Cm d , -.Cm e , -.Cm r , .Cm t , .Cm u , and -.Cm z +.Cm w are ignored by .Xr mandoc 1 . .Pp @@ -57,7 +57,7 @@ html_tblopen(struct html *h, const struct tbl_span *sp) if (TBL_SPAN_FIRST & sp->flags) { h->tbl.len = html_tbl_len; h->tbl.slen = html_tbl_strlen; - tblcalc(&h->tbl, sp); + tblcalc(&h->tbl, sp, 0); } assert(NULL == h->tblt); diff --git a/tbl_layout.c b/tbl_layout.c index b78e8881..004f33cc 100644 --- a/tbl_layout.c +++ b/tbl_layout.c @@ -168,6 +168,9 @@ mod: goto mod; case 'w': /* XXX for now, ignore minimal column width */ goto mod; + case 'x': + cp->flags |= TBL_CELL_WMAX; + goto mod; case 'f': break; case 'r': @@ -91,7 +91,7 @@ term_tbl(struct termp *tp, const struct tbl_span *sp) tp->tbl.slen = term_tbl_strlen; tp->tbl.arg = tp; - tblcalc(&tp->tbl, sp); + tblcalc(&tp->tbl, sp, rmargin - tp->offset); } /* Horizontal frame at the start of boxed tables. */ |