summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc/mdoc_term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-01-02 02:42:07 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-01-02 02:42:07 +0000
commit9dc7df5a86cb463550e48720c3e7d2911ada3a33 (patch)
treead7a834b3dd7475414b09a57cc4ec07a1e45e644 /usr.bin/mandoc/mdoc_term.c
parent1eb9eaeb5cceedbe9d97dec2b66ec67cc4a92cf5 (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.c138
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);