=================================================================== RCS file: /cvs/mandoc/mdoc_term.c,v retrieving revision 1.287 retrieving revision 1.294 diff -u -p -r1.287 -r1.294 --- mandoc/mdoc_term.c 2014/10/28 17:36:19 1.287 +++ mandoc/mdoc_term.c 2014/11/27 16:20:31 1.294 @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.287 2014/10/28 17:36:19 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.294 2014/11/27 16:20:31 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze @@ -51,7 +51,6 @@ struct termact { static size_t a2width(const struct termp *, const char *); static size_t a2height(const struct termp *, const char *); -static size_t a2offs(const struct termp *, const char *); static void print_bvspace(struct termp *, const struct mdoc_node *, @@ -92,7 +91,6 @@ static int termp_bt_pre(DECL_ARGS); static int termp_bx_pre(DECL_ARGS); static int termp_cd_pre(DECL_ARGS); static int termp_d1_pre(DECL_ARGS); -static int termp_es_pre(DECL_ARGS); static int termp_ex_pre(DECL_ARGS); static int termp_fa_pre(DECL_ARGS); static int termp_fd_pre(DECL_ARGS); @@ -112,6 +110,7 @@ static int termp_quote_pre(DECL_ARGS); static int termp_rs_pre(DECL_ARGS); static int termp_rv_pre(DECL_ARGS); static int termp_sh_pre(DECL_ARGS); +static int termp_skip_pre(DECL_ARGS); static int termp_sm_pre(DECL_ARGS); static int termp_sp_pre(DECL_ARGS); static int termp_ss_pre(DECL_ARGS); @@ -184,7 +183,7 @@ static const struct termact termacts[MDOC_MAX] = { { termp_quote_pre, termp_quote_post }, /* Bq */ { termp_xx_pre, NULL }, /* Bsx */ { termp_bx_pre, NULL }, /* Bx */ - { NULL, NULL }, /* Db */ + { termp_skip_pre, NULL }, /* Db */ { NULL, NULL }, /* Dc */ { termp_quote_pre, termp_quote_post }, /* Do */ { termp_quote_pre, termp_quote_post }, /* Dq */ @@ -194,7 +193,7 @@ static const struct termact termacts[MDOC_MAX] = { { termp_quote_pre, termp_quote_post }, /* Eo */ { termp_xx_pre, NULL }, /* Fx */ { termp_bold_pre, NULL }, /* Ms */ - { NULL, NULL }, /* No */ + { termp_li_pre, NULL }, /* No */ { termp_ns_pre, NULL }, /* Ns */ { termp_xx_pre, NULL }, /* Nx */ { termp_xx_pre, NULL }, /* Ox */ @@ -236,7 +235,7 @@ static const struct termact termacts[MDOC_MAX] = { { termp_quote_pre, termp_quote_post }, /* Bro */ { NULL, NULL }, /* Brc */ { NULL, termp____post }, /* %C */ - { termp_es_pre, NULL }, /* Es */ + { termp_skip_pre, NULL }, /* Es */ { termp_quote_pre, termp_quote_post }, /* En */ { termp_xx_pre, NULL }, /* Dx */ { NULL, termp____post }, /* %Q */ @@ -406,6 +405,7 @@ static void print_mdoc_foot(struct termp *p, const void *arg) { const struct mdoc_meta *meta; + size_t sz; meta = (const struct mdoc_meta *)arg; @@ -422,8 +422,9 @@ print_mdoc_foot(struct termp *p, const void *arg) term_vspace(p); p->offset = 0; - p->rmargin = (p->maxrmargin - - term_strlen(p, meta->date) + term_len(p, 1)) / 2; + sz = term_strlen(p, meta->date); + p->rmargin = p->maxrmargin > sz ? + (p->maxrmargin + term_len(p, 1) - sz) / 2 : 0; p->trailspace = 1; p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; @@ -431,7 +432,8 @@ print_mdoc_foot(struct termp *p, const void *arg) term_flushln(p); p->offset = p->rmargin; - p->rmargin = p->maxrmargin - term_strlen(p, meta->os); + sz = term_strlen(p, meta->os); + p->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0; p->flags |= TERMP_NOSPACE; term_word(p, meta->date); @@ -493,7 +495,7 @@ print_mdoc_head(struct termp *p, const void *arg) p->offset = 0; p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ? (p->maxrmargin - vollen + term_len(p, 1)) / 2 : - p->maxrmargin - vollen; + vollen < p->maxrmargin ? p->maxrmargin - vollen : 0; term_word(p, title); term_flushln(p); @@ -550,27 +552,6 @@ a2width(const struct termp *p, const char *v) return(term_hspan(p, &su)); } -static size_t -a2offs(const struct termp *p, const char *v) -{ - struct roffsu su; - - if ('\0' == *v) - return(0); - else if (0 == strcmp(v, "left")) - return(0); - else if (0 == strcmp(v, "indent")) - return(term_len(p, p->defindent + 1)); - else if (0 == strcmp(v, "indent-two")) - return(term_len(p, (p->defindent + 1) * 2)); - else if ( ! a2roffsu(v, &su, SCALE_MAX)) { - SCALE_HS_INIT(&su, term_strlen(p, v)); - su.scale /= term_strlen(p, "0"); - } - - return(term_hspan(p, &su)); -} - /* * 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, @@ -594,16 +575,18 @@ print_bvspace(struct termp *p, /* Do not vspace directly after Ss/Sh. */ - for (nn = n; nn; nn = nn->parent) { - if (MDOC_BLOCK != nn->type) - continue; - if (MDOC_Ss == nn->tok) + nn = n; + while (nn->prev == NULL) { + do { + nn = nn->parent; + if (nn->type == MDOC_ROOT) + return; + } while (nn->type != MDOC_BLOCK); + if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss) return; - if (MDOC_Sh == nn->tok) - return; - if (NULL == nn->prev) - continue; - break; + if (nn->tok == MDOC_It && + nn->parent->parent->norm->Bl.type != LIST_item) + break; } /* A `-column' does not assert vspace within the list. */ @@ -659,7 +642,7 @@ termp_it_pre(DECL_ARGS) width = offset = 0; if (bl->norm->Bl.offs) - offset = a2offs(p, bl->norm->Bl.offs); + offset = a2width(p, bl->norm->Bl.offs); switch (type) { case LIST_column: @@ -893,11 +876,8 @@ termp_it_pre(DECL_ARGS) assert(width); if (MDOC_HEAD == n->type) p->rmargin = p->offset + width; - else { + else p->offset += width; - if (p->rmargin < p->offset) - p->rmargin = p->offset; - } break; case LIST_column: assert(width); @@ -1030,8 +1010,6 @@ termp_nm_pre(DECL_ARGS) MDOC_TEXT == n->prev->child->type ? term_strlen(p, n->prev->child->string) : term_len(p, 5)); - if (p->rmargin < p->offset) - p->rmargin = p->offset; return(1); } @@ -1396,14 +1374,17 @@ static int termp_sh_pre(DECL_ARGS) { - /* No vspace between consecutive `Sh' calls. */ - switch (n->type) { case MDOC_BLOCK: - if (n->prev && MDOC_Sh == n->prev->tok) - if (NULL == n->prev->body->child) - break; - term_vspace(p); + /* + * Vertical space before sections, except + * when the previous section was empty. + */ + if (n->prev == NULL || + MDOC_Sh != n->prev->tok || + (n->prev->body != NULL && + n->prev->body->child != NULL)) + term_vspace(p); break; case MDOC_HEAD: term_fontpush(p, TERMFONT_BOLD); @@ -1581,9 +1562,18 @@ termp_bd_pre(DECL_ARGS) } else if (MDOC_HEAD == n->type) return(0); - if (n->norm->Bd.offs) - p->offset += a2offs(p, n->norm->Bd.offs); + /* Handle the -offset argument. */ + if (n->norm->Bd.offs == NULL || + ! strcmp(n->norm->Bd.offs, "left")) + /* nothing */; + else if ( ! strcmp(n->norm->Bd.offs, "indent")) + p->offset += term_len(p, p->defindent + 1); + else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) + p->offset += term_len(p, (p->defindent + 1) * 2); + else + p->offset += a2width(p, n->norm->Bd.offs); + /* * If -ragged or -filled are specified, the block does nothing * but change the indentation. If -unfilled or -literal are @@ -1848,7 +1838,7 @@ termp_sp_pre(DECL_ARGS) } static int -termp_es_pre(DECL_ARGS) +termp_skip_pre(DECL_ARGS) { return(0); @@ -1865,7 +1855,8 @@ termp_quote_pre(DECL_ARGS) case MDOC_Ao: /* FALLTHROUGH */ case MDOC_Aq: - term_word(p, "<"); + term_word(p, n->parent->prev != NULL && + n->parent->prev->tok == MDOC_An ? "<" : "\\(la"); break; case MDOC_Bro: /* FALLTHROUGH */ @@ -1936,7 +1927,8 @@ termp_quote_post(DECL_ARGS) case MDOC_Ao: /* FALLTHROUGH */ case MDOC_Aq: - term_word(p, ">"); + term_word(p, n->parent->prev != NULL && + n->parent->prev->tok == MDOC_An ? ">" : "\\(ra"); break; case MDOC_Bro: /* FALLTHROUGH */