=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mdoc_term.c,v retrieving revision 1.67 retrieving revision 1.68 diff -c -r1.67 -r1.68 *** src/usr.bin/mandoc/mdoc_term.c 2010/01/01 23:28:03 1.67 --- src/usr.bin/mandoc/mdoc_term.c 2010/01/02 02:42:06 1.68 *************** *** 1,4 **** ! /* $Id: mdoc_term.c,v 1.67 2010/01/01 23:28:03 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * --- 1,4 ---- ! /* $Id: mdoc_term.c,v 1.68 2010/01/02 02:42:06 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * *************** *** 33,39 **** struct termpair { struct termpair *ppair; - int flag; int count; }; --- 33,38 ---- *************** *** 466,477 **** 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); } --- 465,471 ---- if ( ! a2roffsu(arg->value[pos], &su, SCALE_MAX)) SCALE_HS_INIT(&su, strlen(arg->value[pos])); ! return(term_hspan(&su)); } *************** *** 536,541 **** --- 530,539 ---- } + /* + * 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) { *************** *** 544,549 **** --- 542,551 ---- } + /* + * 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) { *************** *** 553,558 **** --- 555,566 ---- } + /* + * 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) *************** *** 572,577 **** --- 580,590 ---- } + /* + * 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, *************** *** 650,657 **** const struct mdoc_node *bl, *nn; char buf[7]; int i, type, keys[3], vals[3]; ! size_t width, offset, ncols; ! int dcol; if (MDOC_BLOCK == n->type) { print_bvspace(p, n->parent->parent, n); --- 663,669 ---- const struct mdoc_node *bl, *nn; char buf[7]; int i, type, keys[3], vals[3]; ! size_t width, offset, ncols, dcol; if (MDOC_BLOCK == n->type) { print_bvspace(p, n->parent->parent, n); *************** *** 660,726 **** bl = n->parent->parent->parent; ! /* Save parent attributes. */ - pair->flag = p->flags; - - /* Get list width and offset. */ - keys[0] = MDOC_Width; keys[1] = MDOC_Offset; keys[2] = MDOC_Column; vals[0] = vals[1] = vals[2] = -1; ! width = offset = 0; - (void)arg_getattrs(keys, vals, 3, bl); - type = arg_listtype(bl); assert(-1 != type); 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. */ 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; /* ! * Use the declared column widths, ! * extended as explained in the preceding paragraph. */ ! if (i < (int)ncols) ! width = a2width(&bl->args->argv[vals[2]], i) + ! (size_t)dcol; /* ! * 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. */ break; default: ! if (vals[0] >= 0) ! width = a2width(&bl->args->argv[vals[0]], 0); break; } --- 672,750 ---- bl = n->parent->parent->parent; ! /* Get list width, offset, and list type from argument list. */ keys[0] = MDOC_Width; keys[1] = MDOC_Offset; keys[2] = MDOC_Column; vals[0] = vals[1] = vals[2] = -1; ! 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]]); 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 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; ! /* 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); + + /* ! * 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) ! break; /* ! * 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) ! 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; } *************** *** 789,799 **** } /* ! * Pad and break control. This is the tricker part. Lists with ! * set right-margins for the head get TERMP_NOBREAK because, if ! * they overrun the margin, they wrap to the new margin. ! * Correspondingly, the body for these types don't left-pad, as ! * the head will pad out to to the right. */ switch (type) { --- 813,822 ---- } /* ! * Pad and break control. This is the tricky part. These flags ! * are documented in term_flushln() in term.c. Note that we're ! * going to unset all of these flags in termp_it_post() when we ! * exit. */ switch (type) { *************** *** 934,940 **** break; case (MDOC_Enum): (pair->ppair->ppair->count)++; ! (void)snprintf(buf, sizeof(buf), "%d.", pair->ppair->ppair->count); term_word(p, buf); break; --- 957,963 ---- break; case (MDOC_Enum): (pair->ppair->ppair->count)++; ! snprintf(buf, sizeof(buf), "%d.", pair->ppair->ppair->count); term_word(p, buf); break; *************** *** 977,983 **** { int type; ! if (MDOC_BODY != n->type && MDOC_HEAD != n->type) return; type = arg_listtype(n->parent->parent->parent); --- 1000,1006 ---- { int type; ! if (MDOC_BLOCK == n->type) return; type = arg_listtype(n->parent->parent->parent); *************** *** 1001,1007 **** break; } ! p->flags = pair->flag; } --- 1024,1040 ---- break; } ! /* ! * Now that our output is flushed, we can reset our tags. Since ! * only `It' sets these flags, we're free to assume that nobody ! * has munged them in the meanwhile. ! */ ! ! p->flags &= ~TERMP_DANGLE; ! p->flags &= ~TERMP_NOBREAK; ! p->flags &= ~TERMP_TWOSPACE; ! p->flags &= ~TERMP_NOLPAD; ! p->flags &= ~TERMP_HANG; } *************** *** 1982,1991 **** { assert(n->child && MDOC_TEXT == n->child->type); ! if (0 == strcmp("on", n->child->string)) { p->flags &= ~TERMP_NONOSPACE; ! p->flags &= ~TERMP_NOSPACE; ! } else p->flags |= TERMP_NONOSPACE; return(0); --- 2015,2023 ---- { assert(n->child && MDOC_TEXT == n->child->type); ! if (0 == strcmp("on", n->child->string)) p->flags &= ~TERMP_NONOSPACE; ! else p->flags |= TERMP_NONOSPACE; return(0);