]> git.cameronkatri.com Git - mandoc.git/blobdiff - out.c
improve documentation of .Fa, .Va, and .Vt;
[mandoc.git] / out.c
diff --git a/out.c b/out.c
index 783a04c56858e8c9295d2d93f166ea0707e8f277..5b08a09abd42b6cd4923885bbc55e3fc31e939c2 100644 (file)
--- a/out.c
+++ b/out.c
@@ -1,7 +1,7 @@
-/*     $Id: out.c,v 1.51 2014/08/12 19:28:16 schwarze Exp $ */
+/*     $Id: out.c,v 1.53 2014/10/14 18:18:05 schwarze Exp $ */
 /*
  * 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 = -1; 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