=================================================================== RCS file: /cvs/mandoc/mdoc_term.c,v retrieving revision 1.72 retrieving revision 1.85 diff -u -p -r1.72 -r1.85 --- mandoc/mdoc_term.c 2009/09/20 11:05:22 1.72 +++ mandoc/mdoc_term.c 2009/09/26 17:35:49 1.85 @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.72 2009/09/20 11:05:22 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.85 2009/09/26 17:35:49 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -106,6 +106,7 @@ static void termp_sq_post(DECL_ARGS); static void termp_ss_post(DECL_ARGS); static void termp_vt_post(DECL_ARGS); +static int termp__t_pre(DECL_ARGS); static int termp_an_pre(DECL_ARGS); static int termp_ap_pre(DECL_ARGS); static int termp_aq_pre(DECL_ARGS); @@ -113,7 +114,6 @@ static int termp_bd_pre(DECL_ARGS); static int termp_bf_pre(DECL_ARGS); static int termp_bold_pre(DECL_ARGS); static int termp_bq_pre(DECL_ARGS); -static int termp_br_pre(DECL_ARGS); static int termp_brq_pre(DECL_ARGS); static int termp_bt_pre(DECL_ARGS); static int termp_cd_pre(DECL_ARGS); @@ -133,7 +133,6 @@ static int termp_nm_pre(DECL_ARGS); static int termp_ns_pre(DECL_ARGS); static int termp_op_pre(DECL_ARGS); static int termp_pf_pre(DECL_ARGS); -static int termp_pp_pre(DECL_ARGS); static int termp_pq_pre(DECL_ARGS); static int termp_qq_pre(DECL_ARGS); static int termp_rs_pre(DECL_ARGS); @@ -155,7 +154,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Os */ { termp_sh_pre, termp_sh_post }, /* Sh */ { termp_ss_pre, termp_ss_post }, /* Ss */ - { termp_pp_pre, NULL }, /* Pp */ + { termp_sp_pre, NULL }, /* Pp */ { termp_d1_pre, termp_d1_post }, /* D1 */ { termp_d1_pre, termp_d1_post }, /* Dl */ { termp_bd_pre, termp_bd_post }, /* Bd */ @@ -191,15 +190,15 @@ static const struct termact termacts[MDOC_MAX] = { { termp_under_pre, termp_vt_post }, /* Vt */ { termp_xr_pre, NULL }, /* Xr */ { NULL, termp____post }, /* %A */ - { NULL, termp____post }, /* %B */ + { termp_under_pre, termp____post }, /* %B */ { NULL, termp____post }, /* %D */ - { NULL, termp____post }, /* %I */ + { termp_under_pre, termp____post }, /* %I */ { termp_under_pre, termp____post }, /* %J */ { NULL, termp____post }, /* %N */ { NULL, termp____post }, /* %O */ { NULL, termp____post }, /* %P */ { NULL, termp____post }, /* %R */ - { termp_under_pre, termp____post }, /* %T */ + { termp__t_pre, termp____post }, /* %T */ { NULL, termp____post }, /* %V */ { NULL, NULL }, /* Ac */ { termp_aq_pre, termp_aq_post }, /* Ao */ @@ -220,7 +219,7 @@ static const struct termact termacts[MDOC_MAX] = { { termp_under_pre, NULL }, /* Em */ { NULL, NULL }, /* Eo */ { termp_xx_pre, NULL }, /* Fx */ - { termp_bold_pre, NULL }, /* Ms */ + { termp_bold_pre, NULL }, /* Ms */ /* FIXME: convert to symbol? */ { NULL, NULL }, /* No */ { termp_ns_pre, NULL }, /* Ns */ { termp_xx_pre, NULL }, /* Nx */ @@ -256,18 +255,18 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Fr */ { termp_ud_pre, NULL }, /* Ud */ { NULL, termp_lb_post }, /* Lb */ - { termp_pp_pre, NULL }, /* Lp */ + { termp_sp_pre, NULL }, /* Lp */ { termp_lk_pre, NULL }, /* Lk */ { termp_under_pre, NULL }, /* Mt */ { termp_brq_pre, termp_brq_post }, /* Brq */ { termp_brq_pre, termp_brq_post }, /* Bro */ { NULL, NULL }, /* Brc */ - { NULL, NULL }, /* %C */ - { NULL, NULL }, /* Es */ - { NULL, NULL }, /* En */ + { NULL, termp____post }, /* %C */ + { NULL, NULL }, /* Es */ /* TODO */ + { NULL, NULL }, /* En */ /* TODO */ { termp_xx_pre, NULL }, /* Dx */ - { NULL, NULL }, /* %Q */ - { termp_br_pre, NULL }, /* br */ + { NULL, termp____post }, /* %Q */ + { termp_sp_pre, NULL }, /* br */ { termp_sp_pre, NULL }, /* sp */ }; @@ -424,6 +423,7 @@ print_foot(DECL_ARGS) } +/* FIXME: put in utility library. */ /* ARGSUSED */ static void print_head(DECL_ARGS) @@ -520,6 +520,7 @@ arg_width(const struct mdoc_argv *arg, int pos) } +/* FIXME: put in utility file for front-ends. */ static int arg_listtype(const struct mdoc_node *n) { @@ -638,15 +639,10 @@ fmt_block_vspace(struct termp *p, const struct mdoc_node *n; term_newln(p); - - if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Compact, bl)) + if (arg_hasattr(MDOC_Compact, bl)) return; - assert(node); - /* - * Search through our prior nodes. If we follow a `Ss' or `Sh', - * then don't vspace. - */ + /* Do not vspace directly after Ss/Sh. */ for (n = node; n; n = n->parent) { if (MDOC_BLOCK != n->type) @@ -660,19 +656,14 @@ fmt_block_vspace(struct termp *p, break; } - /* - * XXX - not documented: a `-column' does not ever assert vspace - * within the list. - */ + /* A `-column' does not assert vspace within the list. */ if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Column, bl)) if (node->prev && MDOC_It == node->prev->tok) return; - /* - * XXX - not documented: a `-diag' without a body does not - * assert a vspace prior to the next element. - */ + /* A `-diag' without body does not vspace. */ + if (MDOC_Bl == bl->tok && arg_hasattr(MDOC_Diag, bl)) if (node->prev && MDOC_It == node->prev->tok) { assert(node->prev->body); @@ -761,14 +752,14 @@ termp_it_pre(DECL_ARGS) * the 0 will be adjusted to default 10 or, if in the * last column case, set to stretch to the margin). */ - for (i = 0, n = node->prev; n && n && - i < (int)bl->args[vals[2]].argv->sz; + for (i = 0, n = node->prev; n && + i < (int)bl->args->argv[vals[2]].sz; n = n->prev, i++) offset += arg_width (&bl->args->argv[vals[2]], i); /* Whether exceeds maximum column. */ - if (i < (int)bl->args[vals[2]].argv->sz) + if (i < (int)bl->args->argv[vals[2]].sz) width = arg_width(&bl->args->argv[vals[2]], i); else width = 0; @@ -1099,13 +1090,12 @@ termp_an_pre(DECL_ARGS) return(1); /* - * XXX: this is poorly documented. If not in the AUTHORS - * section, `An -split' will cause newlines to occur before the - * author name. If in the AUTHORS section, by default, the - * first `An' invocation is nosplit, then all subsequent ones, - * regardless of whether interspersed with other macros/text, - * are split. -split, in this case, will override the condition - * of the implied first -nosplit. + * If not in the AUTHORS section, `An -split' will cause + * newlines to occur before the author name. If in the AUTHORS + * section, by default, the first `An' invocation is nosplit, + * then all subsequent ones, regardless of whether interspersed + * with other macros/text, are split. -split, in this case, + * will override the condition of the implied first -nosplit. */ if (node->sec == SEC_AUTHORS) { @@ -1161,19 +1151,11 @@ termp_ns_pre(DECL_ARGS) /* ARGSUSED */ static int -termp_pp_pre(DECL_ARGS) -{ - - term_vspace(p); - return(1); -} - - -/* ARGSUSED */ -static int termp_rs_pre(DECL_ARGS) { + if (SEC_SEE_ALSO != node->sec) + return(1); if (MDOC_BLOCK == node->type && node->prev) term_vspace(p); return(1); @@ -1359,10 +1341,9 @@ termp_fd_post(DECL_ARGS) static int termp_sh_pre(DECL_ARGS) { - /* - * XXX: undocumented: using two `Sh' macros in sequence has no - * vspace between calls, only a newline. - */ + + /* No vspace between consecutive `Sh' calls. */ + switch (node->type) { case (MDOC_BLOCK): if (node->prev && MDOC_Sh == node->prev->tok) @@ -1425,7 +1406,7 @@ termp_bt_pre(DECL_ARGS) { term_word(p, "is currently in beta test."); - return(1); + return(0); } @@ -1434,7 +1415,8 @@ static void termp_lb_post(DECL_ARGS) { - term_newln(p); + if (SEC_LIBRARY == node->sec) + term_newln(p); } @@ -1526,10 +1508,6 @@ termp_fn_pre(DECL_ARGS) { const struct mdoc_node *n; - assert(node->child && MDOC_TEXT == node->child->type); - - /* FIXME: can be "type funcname" "type varname"... */ - p->bold++; term_word(p, node->child->string); p->bold--; @@ -1594,30 +1572,19 @@ termp_fa_pre(DECL_ARGS) static int termp_bd_pre(DECL_ARGS) { - int i, type; + int i, type; + const struct mdoc_node *nn; - /* - * This is fairly tricky due primarily to crappy documentation. - * If -ragged or -filled are specified, the block does nothing - * but change the indentation. - * - * If, on the other hand, -unfilled or -literal are specified, - * then the game changes. Text is printed exactly as entered in - * the display: if a macro line, a newline is appended to the - * line. Blank lines are allowed. - */ - if (MDOC_BLOCK == node->type) { fmt_block_vspace(p, node, node); return(1); } else if (MDOC_BODY != node->type) return(1); - assert(node->parent->args); + nn = node->parent; - for (type = -1, i = 0; -1 == type && - i < (int)node->parent->args->argc; i++) { - switch (node->parent->args->argv[i].arg) { + for (type = -1, i = 0; i < (int)nn->args->argc; i++) { + switch (nn->args->argv[i].arg) { case (MDOC_Ragged): /* FALLTHROUGH */ case (MDOC_Filled): @@ -1625,32 +1592,33 @@ termp_bd_pre(DECL_ARGS) case (MDOC_Unfilled): /* FALLTHROUGH */ case (MDOC_Literal): - type = node->parent->args->argv[i].arg; + type = nn->args->argv[i].arg; break; + case (MDOC_Offset): + p->offset += arg_offset(&nn->args->argv[i]); + break; default: break; } } + + /* + * If -ragged or -filled are specified, the block does nothing + * but change the indentation. If -unfilled or -literal are + * specified, text is printed exactly as entered in the display: + * for macro lines, a newline is appended to the line. Blank + * lines are allowed. + */ assert(type > -1); - - i = arg_getattr(MDOC_Offset, node->parent); - if (-1 != i) - p->offset += arg_offset(&node->parent->args->argv[i]); - - switch (type) { - case (MDOC_Literal): - /* FALLTHROUGH */ - case (MDOC_Unfilled): - break; - default: + if (MDOC_Literal != type && MDOC_Unfilled != type) return(1); - } - for (node = node->child; node; node = node->next) { - p->flags |= TERMP_NOSPACE; - print_node(p, pair, meta, node); - if (node->next) + for (nn = node->child; nn; nn = nn->next) { + print_node(p, pair, meta, nn); + if (NULL == nn->next) + continue; + if (nn->prev && nn->prev->line < nn->line) term_flushln(p); } @@ -1852,6 +1820,7 @@ termp_in_post(DECL_ARGS) { p->bold++; + p->flags |= TERMP_NOSPACE; term_word(p, ">"); p->bold--; @@ -1876,12 +1845,18 @@ termp_sp_pre(DECL_ARGS) { int i, len; - if (NULL == node->child) { - term_vspace(p); - return(0); + switch (node->tok) { + case (MDOC_sp): + len = node->child ? atoi(node->child->string) : 1; + break; + case (MDOC_br): + len = 0; + break; + default: + len = 1; + break; } - len = atoi(node->child->string); if (0 == len) term_newln(p); for (i = 0; i < len; i++) @@ -1893,16 +1868,6 @@ termp_sp_pre(DECL_ARGS) /* ARGSUSED */ static int -termp_br_pre(DECL_ARGS) -{ - - term_newln(p); - return(1); -} - - -/* ARGSUSED */ -static int termp_brq_pre(DECL_ARGS) { @@ -2079,6 +2044,14 @@ termp____post(DECL_ARGS) { p->flags |= TERMP_NOSPACE; + switch (node->tok) { + case (MDOC__T): + term_word(p, "\\(rq"); + p->flags |= TERMP_NOSPACE; + break; + default: + break; + } term_word(p, node->next ? "," : "."); } @@ -2118,5 +2091,16 @@ termp_under_pre(DECL_ARGS) { p->under++; + return(1); +} + + +/* ARGSUSED */ +static int +termp__t_pre(DECL_ARGS) +{ + + term_word(p, "\\(lq"); + p->flags |= TERMP_NOSPACE; return(1); }