=================================================================== RCS file: /cvs/mandoc/mdoc_term.c,v retrieving revision 1.32 retrieving revision 1.45 diff -u -p -r1.32 -r1.45 --- mandoc/mdoc_term.c 2009/07/12 19:28:46 1.32 +++ mandoc/mdoc_term.c 2009/07/17 12:40:48 1.45 @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.32 2009/07/12 19:28:46 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.45 2009/07/17 12:40:48 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -127,10 +127,10 @@ static int termp__t_pre(DECL_ARGS); static int termp_ap_pre(DECL_ARGS); static int termp_aq_pre(DECL_ARGS); static int termp_ar_pre(DECL_ARGS); -static int termp_at_pre(DECL_ARGS); static int termp_bd_pre(DECL_ARGS); static int termp_bf_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); @@ -148,7 +148,6 @@ static int termp_ft_pre(DECL_ARGS); static int termp_ic_pre(DECL_ARGS); static int termp_in_pre(DECL_ARGS); static int termp_it_pre(DECL_ARGS); -static int termp_lb_pre(DECL_ARGS); static int termp_lk_pre(DECL_ARGS); static int termp_ms_pre(DECL_ARGS); static int termp_mt_pre(DECL_ARGS); @@ -165,9 +164,9 @@ static int termp_rs_pre(DECL_ARGS); static int termp_rv_pre(DECL_ARGS); static int termp_sh_pre(DECL_ARGS); static int termp_sm_pre(DECL_ARGS); +static int termp_sp_pre(DECL_ARGS); static int termp_sq_pre(DECL_ARGS); static int termp_ss_pre(DECL_ARGS); -static int termp_st_pre(DECL_ARGS); static int termp_sx_pre(DECL_ARGS); static int termp_sy_pre(DECL_ARGS); static int termp_ud_pre(DECL_ARGS); @@ -214,7 +213,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Ot */ { termp_pa_pre, NULL }, /* Pa */ { termp_rv_pre, NULL }, /* Rv */ - { termp_st_pre, NULL }, /* St */ + { NULL, NULL }, /* St */ { termp_va_pre, NULL }, /* Va */ { termp_vt_pre, termp_vt_post }, /* Vt */ { termp_xr_pre, NULL }, /* Xr */ @@ -232,7 +231,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Ac */ { termp_aq_pre, termp_aq_post }, /* Ao */ { termp_aq_pre, termp_aq_post }, /* Aq */ - { termp_at_pre, NULL }, /* At */ + { NULL, NULL }, /* At */ { NULL, NULL }, /* Bc */ { termp_bf_pre, NULL }, /* Bf */ { termp_bq_pre, termp_bq_post }, /* Bo */ @@ -283,7 +282,7 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* Hf */ { NULL, NULL }, /* Fr */ { termp_ud_pre, NULL }, /* Ud */ - { termp_lb_pre, termp_lb_post }, /* Lb */ + { NULL, termp_lb_post }, /* Lb */ { termp_pp_pre, NULL }, /* Lp */ { termp_lk_pre, NULL }, /* Lk */ { termp_mt_pre, NULL }, /* Mt */ @@ -295,6 +294,8 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, NULL }, /* En */ { termp_xx_pre, NULL }, /* Dx */ { NULL, NULL }, /* %Q */ + { termp_br_pre, NULL }, /* br */ + { termp_sp_pre, NULL }, /* sp */ }; #ifdef __linux__ @@ -410,7 +411,7 @@ print_foot(struct termp *p, const struct mdoc_meta *me tm = localtime(&meta->date); - if (0 == strftime(buf, p->rmargin, "%B %d, %Y", tm)) + if (0 == strftime(buf, p->rmargin, "%B %e, %Y", tm)) err(1, "strftime"); (void)strlcpy(os, meta->os, p->rmargin); @@ -520,28 +521,26 @@ print_head(struct termp *p, const struct mdoc_meta *me static size_t arg_width(const struct mdoc_argv *arg, int pos) { - size_t v; int i, len; + const char *p; assert(pos < (int)arg->sz && pos >= 0); assert(arg->value[pos]); - if (0 == (len = (int)strlen(arg->value[pos]))) + p = arg->value[pos]; + + if (0 == (len = (int)strlen(p))) return(0); for (i = 0; i < len - 1; i++) - if ( ! isdigit((u_char)arg->value[pos][i])) + if ( ! isdigit((u_char)p[i])) break; - if (i == len - 1) { - if ('n' == arg->value[pos][len - 1] || - 'm' == arg->value[pos][len - 1]) { - v = (size_t)atoi(arg->value[pos]); - return(v + 2); - } + if (i == len - 1) + if ('n' == p[len - 1] || 'm' == p[len - 1]) + return((size_t)atoi(p) + 2); - } - return(strlen(arg->value[pos]) + 2); + return((size_t)len + 2); } @@ -574,34 +573,46 @@ arg_listtype(const struct mdoc_node *n) /* FALLTHROUGH */ case (MDOC_Column): /* FALLTHROUGH */ + case (MDOC_Hang): + /* FALLTHROUGH */ case (MDOC_Ohang): return(n->args->argv[i].arg); default: break; } - /* FIXME: mandated by parser. */ - - errx(1, "list type not supported"); - /* NOTREACHED */ + return(-1); } static size_t arg_offset(const struct mdoc_argv *arg) { + int len, i; + const char *p; assert(*arg->value); - if (0 == strcmp(*arg->value, "left")) + p = *arg->value; + + if (0 == strcmp(p, "left")) return(0); - if (0 == strcmp(*arg->value, "indent")) + if (0 == strcmp(p, "indent")) return(INDENT + 1); - if (0 == strcmp(*arg->value, "indent-two")) + if (0 == strcmp(p, "indent-two")) return((INDENT + 1) * 2); - /* FIXME: needs to support field-widths (10n, etc.). */ + if (0 == (len = (int)strlen(p))) + return(0); - return(strlen(*arg->value)); + for (i = 0; i < len - 1; i++) + if ( ! isdigit((u_char)p[i])) + break; + + if (i == len - 1) + if ('n' == p[len - 1] || 'm' == p[len - 1]) + return((size_t)atoi(p)); + + return((size_t)len); } @@ -704,7 +715,7 @@ termp_it_pre(DECL_ARGS) { const struct mdoc_node *bl, *n; char buf[7]; - int i, type, keys[3], vals[3], sv; + int i, type, keys[3], vals[3]; size_t width, offset; if (MDOC_BLOCK == node->type) @@ -729,6 +740,7 @@ termp_it_pre(DECL_ARGS) (void)arg_getattrs(keys, vals, 3, bl); type = arg_listtype(bl); + assert(-1 != type); /* Calculate real width and offset. */ @@ -755,7 +767,7 @@ termp_it_pre(DECL_ARGS) /* * List-type can override the width in the case of fixed-head * values (bullet, dash/hyphen, enum). Tags need a non-zero - * offset. + * offset. FIXME: double-check that correct. */ switch (type) { @@ -771,6 +783,10 @@ termp_it_pre(DECL_ARGS) if (width < 5) width = 5; break; + case (MDOC_Hang): + if (0 == width) + width = 8; + break; case (MDOC_Tag): if (0 == width) width = 10; @@ -785,9 +801,6 @@ termp_it_pre(DECL_ARGS) */ switch (type) { - case (MDOC_Diag): - term_word(p, "\\ "); - /* FALLTHROUGH */ case (MDOC_Inset): if (MDOC_BODY == node->type) p->flags &= ~TERMP_NOSPACE; @@ -828,16 +841,30 @@ termp_it_pre(DECL_ARGS) case (MDOC_Enum): /* FALLTHROUGH */ case (MDOC_Hyphen): - /* FALLTHROUGH */ + if (MDOC_HEAD == node->type) + p->flags |= TERMP_NOBREAK; + else + p->flags |= TERMP_NOLPAD; + break; + case (MDOC_Hang): + if (MDOC_HEAD == node->type) + p->flags |= TERMP_NOBREAK; + else + p->flags |= TERMP_NOLPAD; + + if (MDOC_HEAD == node->type) + p->flags |= TERMP_HANG; + break; case (MDOC_Tag): if (MDOC_HEAD == node->type) p->flags |= TERMP_NOBREAK; else p->flags |= TERMP_NOLPAD; - if (MDOC_HEAD == node->type && MDOC_Tag == type) - if (NULL == node->next || - NULL == node->next->child) - p->flags |= TERMP_NONOBREAK; + + if (MDOC_HEAD != node->type) + break; + if (NULL == node->next || NULL == node->next->child) + p->flags |= TERMP_DANGLE; break; case (MDOC_Column): if (MDOC_HEAD == node->type) { @@ -875,6 +902,8 @@ termp_it_pre(DECL_ARGS) /* FALLTHROUGH */ case (MDOC_Hyphen): /* FALLTHROUGH */ + case (MDOC_Hang): + /* FALLTHROUGH */ case (MDOC_Tag): if (MDOC_HEAD == node->type) p->rmargin = p->offset + width; @@ -893,18 +922,19 @@ termp_it_pre(DECL_ARGS) * HEAD character (temporarily bold, in some cases). */ - sv = p->flags; if (MDOC_HEAD == node->type) switch (type) { case (MDOC_Bullet): p->flags |= TERMP_BOLD; term_word(p, "\\[bu]"); + p->flags &= ~TERMP_BOLD; break; case (MDOC_Dash): /* FALLTHROUGH */ case (MDOC_Hyphen): p->flags |= TERMP_BOLD; term_word(p, "\\(hy"); + p->flags &= ~TERMP_BOLD; break; case (MDOC_Enum): (pair->ppair->ppair->count)++; @@ -916,8 +946,6 @@ termp_it_pre(DECL_ARGS) break; } - p->flags = sv; /* Restore saved flags. */ - /* * If we're not going to process our children, indicate so here. */ @@ -957,9 +985,11 @@ termp_it_post(DECL_ARGS) return; type = arg_listtype(node->parent->parent->parent); + assert(-1 != type); switch (type) { case (MDOC_Diag): + term_word(p, "\\ "); /* FALLTHROUGH */ case (MDOC_Item): /* FALLTHROUGH */ @@ -1043,18 +1073,6 @@ termp_pp_pre(DECL_ARGS) /* ARGSUSED */ static int -termp_st_pre(DECL_ARGS) -{ - const char *cp; - - if (node->child && (cp = mdoc_a2st(node->child->string))) - term_word(p, cp); - return(0); -} - - -/* ARGSUSED */ -static int termp_rs_pre(DECL_ARGS) { @@ -1070,13 +1088,10 @@ termp_rv_pre(DECL_ARGS) { int i; - /* FIXME: mandated by parser. */ + i = arg_getattr(MDOC_Std, node); + assert(-1 != i); + assert(node->args->argv[i].sz); - if (-1 == (i = arg_getattr(MDOC_Std, node))) - errx(1, "expected -std argument"); - if (1 != node->args->argv[i].sz) - errx(1, "expected -std argument"); - term_newln(p); term_word(p, "The"); @@ -1105,13 +1120,10 @@ termp_ex_pre(DECL_ARGS) { int i; - /* FIXME: mandated by parser? */ + i = arg_getattr(MDOC_Std, node); + assert(-1 != i); + assert(node->args->argv[i].sz); - if (-1 == (i = arg_getattr(MDOC_Std, node))) - errx(1, "expected -std argument"); - if (1 != node->args->argv[i].sz) - errx(1, "expected -std argument"); - term_word(p, "The"); p->flags |= ttypes[TTYPE_PROG]; term_word(p, *node->args->argv[i].value); @@ -1130,13 +1142,8 @@ termp_nd_pre(DECL_ARGS) if (MDOC_BODY != node->type) return(1); - /* - * XXX: signed off by jmc@openbsd.org. This technically - * produces a minus sign after the Nd, which is wrong, but is - * consistent with the historic OpenBSD tmac file. - */ #if defined(__OpenBSD__) || defined(__linux__) - term_word(p, "\\-"); + term_word(p, "\\(en"); #else term_word(p, "\\(em"); #endif @@ -1304,23 +1311,6 @@ termp_bt_pre(DECL_ARGS) /* ARGSUSED */ -static int -termp_lb_pre(DECL_ARGS) -{ - const char *lb; - - assert(node->child && MDOC_TEXT == node->child->type); - lb = mdoc_a2lib(node->child->string); - if (lb) { - term_word(p, lb); - return(0); - } - term_word(p, "library"); - return(1); -} - - -/* ARGSUSED */ static void termp_lb_post(DECL_ARGS) { @@ -1844,24 +1834,37 @@ termp_in_post(DECL_ARGS) /* ARGSUSED */ static int -termp_at_pre(DECL_ARGS) +termp_sp_pre(DECL_ARGS) { - const char *att; + int i, len; - att = NULL; + if (NULL == node->child) { + term_vspace(p); + return(0); + } - if (node->child) - att = mdoc_a2att(node->child->string); - if (NULL == att) - att = "AT&T UNIX"; + len = atoi(node->child->string); + if (0 == len) + term_newln(p); + for (i = 0; i < len; i++) + term_vspace(p); - term_word(p, att); return(0); } /* ARGSUSED */ static int +termp_br_pre(DECL_ARGS) +{ + + term_newln(p); + return(1); +} + + +/* ARGSUSED */ +static int termp_brq_pre(DECL_ARGS) { @@ -1941,13 +1944,12 @@ termp_fo_pre(DECL_ARGS) const struct mdoc_node *n; if (MDOC_BODY == node->type) { + p->flags |= TERMP_NOSPACE; term_word(p, "("); p->flags |= TERMP_NOSPACE; return(1); } else if (MDOC_HEAD != node->type) return(1); - - /* XXX - groff shows only first parameter */ p->flags |= ttypes[TTYPE_FUNC_NAME]; for (n = node->child; n; n = n->next) {