=================================================================== RCS file: /cvs/mandoc/mdoc_term.c,v retrieving revision 1.107 retrieving revision 1.108 diff -u -p -r1.107 -r1.108 --- mandoc/mdoc_term.c 2010/01/01 17:14:30 1.107 +++ mandoc/mdoc_term.c 2010/01/01 18:01:40 1.108 @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.107 2010/01/01 17:14:30 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.108 2010/01/01 18:01:40 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -470,12 +470,7 @@ a2width(const struct mdoc_argv *arg, int pos) if ( ! a2roffsu(arg->value[pos], &su, SCALE_MAX)) SCALE_HS_INIT(&su, strlen(arg->value[pos])); - /* - * This is a bit if a magic number on groff's part. Be careful - * in changing it, as the MDOC_Column handler will subtract one - * from this for >5 columns (don't go below zero!). - */ - return(term_hspan(&su) + 2); + return(term_hspan(&su)); } @@ -540,6 +535,10 @@ a2offs(const struct mdoc_argv *arg) } +/* + * Return 1 if an argument has a particular argument value or 0 if it + * does not. See arg_getattr(). + */ static int arg_hasattr(int arg, const struct mdoc_node *n) { @@ -548,6 +547,10 @@ arg_hasattr(int arg, const struct mdoc_node *n) } +/* + * Get the index of an argument in a node's argument list or -1 if it + * does not exist. See arg_getattrs(). + */ static int arg_getattr(int v, const struct mdoc_node *n) { @@ -557,6 +560,12 @@ arg_getattr(int v, const struct mdoc_node *n) } +/* + * Walk through the argument list for a node and fill an array "vals" + * with the positions of the argument structures listed in "keys". + * Return the number of elements that were written into "vals", which + * can be zero. + */ static int arg_getattrs(const int *keys, int *vals, size_t sz, const struct mdoc_node *n) @@ -576,6 +585,11 @@ arg_getattrs(const int *keys, int *vals, } +/* + * Determine how much space to print out before block elements of `It' + * (and thus `Bl') and `Bd'. And then go ahead and print that space, + * too. + */ static void print_bvspace(struct termp *p, const struct mdoc_node *bl, @@ -654,8 +668,7 @@ termp_it_pre(DECL_ARGS) const struct mdoc_node *bl, *nn; char buf[7]; int i, type, keys[3], vals[3]; - size_t width, offset, ncols; - int dcol; + size_t width, offset, ncols, dcol; if (MDOC_BLOCK == n->type) { print_bvspace(p, n->parent->parent, n); @@ -668,7 +681,7 @@ termp_it_pre(DECL_ARGS) pair->flag = p->flags; - /* Get list width and offset. */ + /* Get list width, offset, and list type from argument list. */ keys[0] = MDOC_Width; keys[1] = MDOC_Offset; @@ -676,55 +689,71 @@ termp_it_pre(DECL_ARGS) vals[0] = vals[1] = vals[2] = -1; - width = offset = 0; + arg_getattrs(keys, vals, 3, bl); - (void)arg_getattrs(keys, vals, 3, bl); - type = arg_listtype(bl); assert(-1 != type); + /* + * First calculate width and offset. This is pretty easy unless + * we're a -column list, in which case all prior columns must + * be accounted for. + */ + + width = offset = 0; + if (vals[1] >= 0) offset = a2offs(&bl->args->argv[vals[1]]); - /* Calculate real width and offset. */ - switch (type) { case (MDOC_Column): if (MDOC_BODY == n->type) break; - /* - * Imitate groff's column handling. - * For each earlier column, add its width. - * For less than 5 columns, add two more blanks per column. - * For exactly 5 columns, add only one more blank per column. - * For more than 5 columns, SUBTRACT one column. We can - * do this because a2width() pads exactly 2 spaces. + * Imitate groff's column handling: + * - For each earlier column, add its width. + * - For less than 5 columns, add four more blanks per + * column. + * - For exactly 5 columns, add three more blank per + * column. + * - For more than 5 columns, add only one column. */ ncols = bl->args->argv[vals[2]].sz; - dcol = ncols < 5 ? 2 : ncols == 5 ? 1 : -1; - for (i=0, nn=n->prev; nn && i < (int)ncols; nn=nn->prev, i++) - offset += a2width(&bl->args->argv[vals[2]], i) + - (size_t)dcol; + /* LINTED */ + dcol = ncols < 5 ? 4 : ncols == 5 ? 3 : 1; + for (i = 0, nn = n->prev; + nn && i < (int)ncols; + nn = nn->prev, i++) + offset += dcol + a2width + (&bl->args->argv[vals[2]], i); + + /* - * Use the declared column widths, - * extended as explained in the preceding paragraph. + * When exceeding the declared number of columns, leave + * the remaining widths at 0. This will later be + * adjusted to the default width of 10, or, for the last + * column, stretched to the right margin. */ - if (i < (int)ncols) - width = a2width(&bl->args->argv[vals[2]], i) + - (size_t)dcol; + if (i >= (int)ncols) + break; /* - * When exceeding the declared number of columns, - * leave the remaining widths at 0. - * This will later be adjusted to the default width of 10, - * or, for the last column, stretched to the right margin. + * Use the declared column widths, extended as explained + * in the preceding paragraph. */ + width = a2width(&bl->args->argv[vals[2]], i) + dcol; break; default: - if (vals[0] >= 0) - width = a2width(&bl->args->argv[vals[0]], 0); + if (vals[0] < 0) + break; + + /* + * Note: buffer the width by 2, which is groff's magic + * number for buffering single arguments. See the above + * handling for column for how this changes. + */ + width = a2width(&bl->args->argv[vals[0]], 0) + 2; break; }