From faf0f4ffb473b01c18346decdde9edc628919365 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Wed, 17 Jun 2009 14:08:47 +0000 Subject: `Bl -column' now correctly handles tail entries (Bl -column -more... arg0...). --- mdoc.7 | 4 ++-- mdoc_action.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ mdoc_argv.c | 8 +++----- mdoc_validate.c | 48 +++++++++++++++++++++++++++++++----------------- 4 files changed, 87 insertions(+), 24 deletions(-) diff --git a/mdoc.7 b/mdoc.7 index 621c6f28..350bd2cb 100644 --- a/mdoc.7 +++ b/mdoc.7 @@ -301,7 +301,7 @@ some .Pc don't have heads. .Pp -.Bl -column "MacroX" "CallableX" "ParsableX" "Closing" -compact -offset XXXX +.Bl -column -compact -offset XXXX "MacroX" "CallableX" "ParsableX" "Closing" .It Em Macro Ta Em Callable Ta Em Parsable Ta Em Closing .It \&.Sh Ta \&No Ta \&No Ta \&.Sh .It \&.Ss Ta \&No Ta \&No Ta \&.Sh, \&.Ss @@ -313,7 +313,7 @@ None of these macros are callable or parsed. The last column indicates the explicit scope rules. All contains bodies, some may contain heads .Pq So \&Bf Sc . .Pp -.Bl -column "MacroX" "CallableX" "ParsableX" "closed by XXX" -compact -offset XXXX +.Bl -column -compact -offset XXXX "MacroX" "CallableX" "ParsableX" "closed by XXX" .It Em Macro Ta Em Callable Ta Em Parsable Ta Em Scope .It \&.Bd Ta \&No Ta \&No Ta closed by \&.Ed .It \&.Ed Ta \&No Ta \&No Ta opened by \&.Bd diff --git a/mdoc_action.c b/mdoc_action.c index 0b7face0..9d8d819d 100644 --- a/mdoc_action.c +++ b/mdoc_action.c @@ -51,6 +51,7 @@ static int concat(struct mdoc *, const struct mdoc_node *, static int post_ar(POST_ARGS); static int post_bl(POST_ARGS); +static int post_bl_head(POST_ARGS); static int post_bl_width(POST_ARGS); static int post_bl_tagwidth(POST_ARGS); static int post_dd(POST_ARGS); @@ -633,11 +634,61 @@ post_bl_width(struct mdoc *m) } +static int +post_bl_head(POST_ARGS) +{ + int i, c; + struct mdoc_node *n, *nn, *nnp; + + if (NULL == m->last->child) + return(1); + + n = m->last->parent; + assert(n->args); + + for (c = 0; c < (int)n->args->argc; c++) + if (MDOC_Column == n->args->argv[c].arg) + break; + + /* Only process -column. */ + + if (c == (int)n->args->argc) + return(1); + + assert(0 == n->args->argv[c].sz); + + /* + * Accomodate for new-style groff column syntax. Shuffle the + * child nodes, all of which must be TEXT, as arguments for the + * column field. Then, delete the head children. + */ + + for (i = 0, nn = m->last->child; nn; nn = nn->next, i++) + /* Count children. */; + + n->args->argv[c].sz = i; + n->args->argv[c].value = malloc(i * sizeof(char *)); + + for (i = 0, nn = m->last->child; nn; i++) { + n->args->argv[c].value[i] = nn->string; + nn->string = NULL; + nnp = nn; + nn = nn->next; + mdoc_node_free(nnp); + } + + m->last->child = NULL; + return(1); +} + + static int post_bl(POST_ARGS) { int i, r, len; + if (MDOC_HEAD == m->last->type) + return(post_bl_head(m)); if (MDOC_BLOCK != m->last->type) return(1); diff --git a/mdoc_argv.c b/mdoc_argv.c index 9339dc8e..6ac75d04 100644 --- a/mdoc_argv.c +++ b/mdoc_argv.c @@ -33,6 +33,7 @@ */ /* FIXME .Bf Li raises "macro-like parameter". */ +/* FIXME .Bl -column should deprecate old-groff syntax. */ #define ARGS_QUOTED (1 << 0) #define ARGS_DELIM (1 << 1) @@ -118,7 +119,7 @@ static int mdoc_argflags[MDOC_MAX] = { ARGS_DELIM | ARGS_QUOTED, /* Dl */ 0, /* Bd */ 0, /* Ed */ - 0, /* Bl */ + ARGS_QUOTED, /* Bl */ 0, /* El */ 0, /* It */ ARGS_DELIM, /* Ad */ @@ -781,10 +782,7 @@ argv_multi(struct mdoc *mdoc, int line, return(verr(mdoc, EMALLOC)); } - if (v->sz) - return(1); - - return(perr(mdoc, line, ppos, EARGVAL)); + return(1); } diff --git a/mdoc_validate.c b/mdoc_validate.c index c58703b5..7d44f20c 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -46,6 +46,7 @@ enum merr { EMULTILIST, EARGREP, EBOOL, + ECOLMIS, ENESTDISP }; @@ -138,6 +139,7 @@ static int post_args(POST_ARGS); static int post_at(POST_ARGS); static int post_bf(POST_ARGS); static int post_bl(POST_ARGS); +static int post_bl_head(POST_ARGS); static int post_it(POST_ARGS); static int post_nm(POST_ARGS); static int post_root(POST_ARGS); @@ -174,7 +176,7 @@ static v_post posts_wtext[] = { ewarn_ge1, NULL }; static v_post posts_notext[] = { eerr_eq0, NULL }; static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL }; static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL }; -static v_post posts_bl[] = { herr_eq0, bwarn_ge1, post_bl, NULL }; +static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL }; static v_post posts_it[] = { post_it, NULL }; static v_post posts_in[] = { ewarn_eq1, NULL }; static v_post posts_ss[] = { herr_ge1, NULL }; @@ -425,6 +427,9 @@ perr(struct mdoc *m, int line, int pos, enum merr type) case (ENODATA): p = "document has no data"; break; + case (ECOLMIS): + p = "column syntax style mismatch"; + break; case (EATT): p = "expected valid AT&T symbol"; break; @@ -879,22 +884,6 @@ pre_bl(PRE_ARGS) break; } - /* - * General validation of fields. - */ - - switch (type) { - case (MDOC_Column): - assert(col >= 0); - if (0 == n->args->argv[col].sz) - break; - if ( ! nwarn(mdoc, n, WDEPCOL)) - return(0); - break; - default: - break; - } - return(1); } @@ -1256,11 +1245,36 @@ post_it(POST_ARGS) } +static int +post_bl_head(POST_ARGS) +{ + int i; + const struct mdoc_node *n; + + n = mdoc->last->parent; + assert(n->args); + + for (i = 0; i < (int)n->args->argc; i++) + if (n->args->argv[i].arg == MDOC_Column) + break; + + if (i == (int)n->args->argc) + return(1); + + if (n->args->argv[i].sz && mdoc->last->child) + return(nerr(mdoc, n, ECOLMIS)); + + return(1); +} + + static int post_bl(POST_ARGS) { struct mdoc_node *n; + if (MDOC_HEAD == mdoc->last->type) + return(post_bl_head(mdoc)); if (MDOC_BODY != mdoc->last->type) return(1); if (NULL == mdoc->last->child) -- cgit