summaryrefslogtreecommitdiffstats
path: root/out.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-10-14 02:16:06 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-10-14 02:16:06 +0000
commit2db1b6bde4abe38f4836e766eac615660b2f85c2 (patch)
treef103cfddb098081641c520d96c4a4cb17d77c915 /out.c
parent619229efd1f5f1aefbec0666e7effe0039234d0c (diff)
downloadmandoc-2db1b6bde4abe38f4836e766eac615660b2f85c2.tar.gz
Rudimentary implementation of the e, x, and z table layout modifiers
to equalize, maximize, and ignore the width of columns. Does not yet take vertical rulers into account, and does not do line breaks within table cells. Considerably improves the lftp(1) manual; issue noticed by sthen@.
Diffstat (limited to 'out.c')
-rw-r--r--out.c74
1 files changed, 69 insertions, 5 deletions
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