diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-01-02 02:42:07 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2010-01-02 02:42:07 +0000 |
commit | 9dc7df5a86cb463550e48720c3e7d2911ada3a33 (patch) | |
tree | ad7a834b3dd7475414b09a57cc4ec07a1e45e644 /usr.bin/mandoc/mdoc_term.c | |
parent | 1eb9eaeb5cceedbe9d97dec2b66ec67cc4a92cf5 (diff) |
complete the sync to 1.9.15-pre2: mostly minor fixes
* bugfix: do not restore TERMP flags when leaving lists, just reset them
* and a few HTML fixes
* clarity: return width from a2width, not width+2, and adapt to it
* manual: document .Bl and .Fl
* portability: no need to escape '%' in macro names
Diffstat (limited to 'usr.bin/mandoc/mdoc_term.c')
-rw-r--r-- | usr.bin/mandoc/mdoc_term.c | 138 |
1 files changed, 85 insertions, 53 deletions
diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c index 9688fca09d3..b3e3f0116d1 100644 --- a/usr.bin/mandoc/mdoc_term.c +++ b/usr.bin/mandoc/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.67 2010/01/01 23:28:03 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.68 2010/01/02 02:42:06 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> * @@ -33,7 +33,6 @@ struct termpair { struct termpair *ppair; - int flag; int count; }; @@ -466,12 +465,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)); } @@ -536,6 +530,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) { @@ -544,6 +542,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) { @@ -553,6 +555,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) @@ -572,6 +580,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, @@ -650,8 +663,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); @@ -660,11 +672,7 @@ termp_it_pre(DECL_ARGS) bl = n->parent->parent->parent; - /* Save parent attributes. */ - - 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; @@ -672,55 +680,71 @@ termp_it_pre(DECL_ARGS) vals[0] = vals[1] = vals[2] = -1; - width = offset = 0; - - (void)arg_getattrs(keys, vals, 3, bl); + 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; } @@ -789,11 +813,10 @@ termp_it_pre(DECL_ARGS) } /* - * 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. + * 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,7 +957,7 @@ termp_it_pre(DECL_ARGS) break; case (MDOC_Enum): (pair->ppair->ppair->count)++; - (void)snprintf(buf, sizeof(buf), "%d.", + snprintf(buf, sizeof(buf), "%d.", pair->ppair->ppair->count); term_word(p, buf); break; @@ -977,7 +1000,7 @@ termp_it_post(DECL_ARGS) { int type; - if (MDOC_BODY != n->type && MDOC_HEAD != n->type) + if (MDOC_BLOCK == n->type) return; type = arg_listtype(n->parent->parent->parent); @@ -1001,7 +1024,17 @@ termp_it_post(DECL_ARGS) break; } - p->flags = pair->flag; + /* + * 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,10 +2015,9 @@ termp_sm_pre(DECL_ARGS) { assert(n->child && MDOC_TEXT == n->child->type); - if (0 == strcmp("on", n->child->string)) { + if (0 == strcmp("on", n->child->string)) p->flags &= ~TERMP_NONOSPACE; - p->flags &= ~TERMP_NOSPACE; - } else + else p->flags |= TERMP_NONOSPACE; return(0); |