summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mandoc.h1
-rw-r--r--out.c74
-rw-r--r--out.h4
-rw-r--r--tbl.716
-rw-r--r--tbl_html.c2
-rw-r--r--tbl_layout.c3
-rw-r--r--tbl_term.c2
7 files changed, 91 insertions, 11 deletions
diff --git a/mandoc.h b/mandoc.h
index bb8e51a2..21b131ab 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -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;
};
diff --git a/out.c b/out.c
index cd33710e..69bda82e 100644
--- a/out.c
+++ b/out.c
@@ -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
diff --git a/out.h b/out.h
index 12a2f43f..f5cb962a 100644
--- a/out.h
+++ b/out.h
@@ -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
diff --git a/tbl.7 b/tbl.7
index 5157f1bb..986ed674 100644
--- a/tbl.7
+++ b/tbl.7
@@ -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
diff --git a/tbl_html.c b/tbl_html.c
index 033946de..03dd203e 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -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':
diff --git a/tbl_term.c b/tbl_term.c
index 52ef73ca..31dabe81 100644
--- a/tbl_term.c
+++ b/tbl_term.c
@@ -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. */