=================================================================== RCS file: /cvs/mandoc/mdoc_man.c,v retrieving revision 1.103 retrieving revision 1.111 diff -u -p -r1.103 -r1.111 --- mandoc/mdoc_man.c 2017/02/16 03:00:23 1.103 +++ mandoc/mdoc_man.c 2017/05/05 02:06:19 1.111 @@ -1,4 +1,4 @@ -/* $Id: mdoc_man.c,v 1.103 2017/02/16 03:00:23 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.111 2017/05/05 02:06:19 schwarze Exp $ */ /* * Copyright (c) 2011-2017 Ingo Schwarze * @@ -20,6 +20,7 @@ #include #include +#include #include #include "mandoc_aux.h" @@ -44,6 +45,7 @@ static int cond_body(DECL_ARGS); static int cond_head(DECL_ARGS); static void font_push(char); static void font_pop(void); +static int man_strlen(const char *); static void mid_it(void); static void post__t(DECL_ARGS); static void post_aq(DECL_ARGS); @@ -92,6 +94,7 @@ static int pre_fl(DECL_ARGS); static int pre_fn(DECL_ARGS); static int pre_fo(DECL_ARGS); static int pre_ft(DECL_ARGS); +static int pre_Ft(DECL_ARGS); static int pre_in(DECL_ARGS); static int pre_it(DECL_ARGS); static int pre_lk(DECL_ARGS); @@ -118,8 +121,7 @@ static void print_width(const struct mdoc_bl *, static void print_count(int *); static void print_node(DECL_ARGS); -static const struct manact manacts[MDOC_MAX + 1] = { - { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */ +static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = { { NULL, NULL, NULL, NULL, NULL }, /* Dd */ { NULL, NULL, NULL, NULL, NULL }, /* Dt */ { NULL, NULL, NULL, NULL, NULL }, /* Os */ @@ -135,6 +137,7 @@ static const struct manact manacts[MDOC_MAX + 1] = { { NULL, pre_it, post_it, NULL, NULL }, /* It */ { NULL, pre_em, post_font, NULL, NULL }, /* Ad */ { NULL, pre_an, NULL, NULL, NULL }, /* An */ + { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */ { NULL, pre_em, post_font, NULL, NULL }, /* Ar */ { NULL, pre_sy, post_font, NULL, NULL }, /* Cd */ { NULL, pre_sy, post_font, NULL, NULL }, /* Cm */ @@ -146,14 +149,14 @@ static const struct manact manacts[MDOC_MAX + 1] = { { NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */ { NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */ { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */ - { NULL, pre_ft, post_font, NULL, NULL }, /* Ft */ + { NULL, pre_Ft, post_font, NULL, NULL }, /* Ft */ { NULL, pre_sy, post_font, NULL, NULL }, /* Ic */ { NULL, pre_in, post_in, NULL, NULL }, /* In */ { NULL, pre_li, post_font, NULL, NULL }, /* Li */ { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */ { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */ { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */ - { NULL, pre_ft, post_font, NULL, NULL }, /* Ot */ + { NULL, pre_Ft, post_font, NULL, NULL }, /* Ot */ { NULL, pre_em, post_font, NULL, NULL }, /* Pa */ { NULL, pre_ex, NULL, NULL, NULL }, /* Rv */ { NULL, NULL, NULL, NULL, NULL }, /* St */ @@ -237,13 +240,12 @@ static const struct manact manacts[MDOC_MAX + 1] = { { cond_body, pre_en, post_en, NULL, NULL }, /* En */ { NULL, NULL, NULL, NULL, NULL }, /* Dx */ { NULL, NULL, post_percent, NULL, NULL }, /* %Q */ - { NULL, pre_br, NULL, NULL, NULL }, /* br */ { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */ { NULL, NULL, post_percent, NULL, NULL }, /* %U */ { NULL, NULL, NULL, NULL, NULL }, /* Ta */ { NULL, pre_ll, post_sp, NULL, NULL }, /* ll */ - { NULL, NULL, NULL, NULL, NULL }, /* ROOT */ }; +static const struct manact *const manacts = __manacts - MDOC_Dd; static int outflags; #define MMAN_spc (1 << 0) /* blank character before next word */ @@ -274,6 +276,49 @@ static struct { } fontqueue; +static int +man_strlen(const char *cp) +{ + size_t rsz; + int skip, sz; + + sz = 0; + skip = 0; + for (;;) { + rsz = strcspn(cp, "\\"); + if (rsz) { + cp += rsz; + if (skip) { + skip = 0; + rsz--; + } + sz += rsz; + } + if ('\0' == *cp) + break; + cp++; + switch (mandoc_escape(&cp, NULL, NULL)) { + case ESCAPE_ERROR: + return sz; + case ESCAPE_UNICODE: + case ESCAPE_NUMBERED: + case ESCAPE_SPECIAL: + case ESCAPE_OVERSTRIKE: + if (skip) + skip = 0; + else + sz++; + break; + case ESCAPE_SKIPCHAR: + skip = 1; + break; + default: + break; + } + } + return sz; +} + static void font_push(char newfont) { @@ -447,7 +492,7 @@ print_offs(const char *v, int keywords) return; } } else - sz = strlen(v); + sz = man_strlen(v); /* * We are inside an enclosing list. @@ -485,13 +530,13 @@ print_width(const struct mdoc_bl *bl, const struct rof numeric = 0; } } else - sz = strlen(bl->width); + sz = man_strlen(bl->width); /* XXX Rough estimation, might have multiple parts. */ if (bl->type == LIST_enum) chsz = (bl->count > 8) + 1; else if (child != NULL && child->type == ROFFT_TEXT) - chsz = strlen(child->string); + chsz = man_strlen(child->string); else chsz = 0; @@ -607,7 +652,19 @@ print_node(DECL_ARGS) outflags &= ~(MMAN_spc | MMAN_spc_force); else if (outflags & MMAN_Sm) outflags |= MMAN_spc; + } else if (n->tok < ROFF_MAX) { + switch (n->tok) { + case ROFF_br: + do_sub = pre_br(meta, n); + break; + case ROFF_ft: + do_sub = pre_ft(meta, n); + break; + default: + abort(); + } } else { + assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); /* * Conditionally run the pre-node action handler for a * node. @@ -715,10 +772,8 @@ static int pre__t(DECL_ARGS) { - if (n->parent && MDOC_Rs == n->parent->tok && - n->parent->norm->Rs.quote_T) { - print_word(""); - putchar('\"'); + if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) { + print_word("\\(lq"); outflags &= ~MMAN_spc; } else font_push('I'); @@ -729,11 +784,9 @@ static void post__t(DECL_ARGS) { - if (n->parent && MDOC_Rs == n->parent->tok && - n->parent->norm->Rs.quote_T) { + if (n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) { outflags &= ~MMAN_spc; - print_word(""); - putchar('\"'); + print_word("\\(rq"); } else font_pop(); post_percent(meta, n); @@ -1265,7 +1318,7 @@ post_fo(DECL_ARGS) } static int -pre_ft(DECL_ARGS) +pre_Ft(DECL_ARGS) { pre_syn(n); @@ -1274,6 +1327,15 @@ pre_ft(DECL_ARGS) } static int +pre_ft(DECL_ARGS) +{ + print_line(".ft", 0); + print_word(n->child->string); + outflags |= MMAN_nl; + return 0; +} + +static int pre_in(DECL_ARGS) { @@ -1468,23 +1530,40 @@ static int pre_lk(DECL_ARGS) { const struct roff_node *link, *descr; + int display; - if (NULL == (link = n->child)) + if ((link = n->child) == NULL) return 0; - if (NULL != (descr = link->next)) { + /* Link text. */ + if ((descr = link->next) != NULL && !(descr->flags & NODE_DELIMC)) { font_push('I'); - while (NULL != descr) { + while (descr != NULL && !(descr->flags & NODE_DELIMC)) { print_word(descr->string); descr = descr->next; } - print_word(":"); font_pop(); + print_word(":"); } + /* Link target. */ + display = man_strlen(link->string) >= 26; + if (display) { + print_line(".RS", MMAN_Bk_susp); + print_word("6n"); + outflags |= MMAN_nl; + } font_push('B'); print_word(link->string); font_pop(); + + /* Trailing punctuation. */ + while (descr != NULL) { + print_word(descr->string); + descr = descr->next; + } + if (display) + print_line(".RE", MMAN_nl); return 0; } @@ -1522,7 +1601,7 @@ pre_nm(DECL_ARGS) if (NULL == n->parent->prev) outflags |= MMAN_sp; print_block(".HP", 0); - printf(" %zun", strlen(name) + 1); + printf(" %dn", man_strlen(name) + 1); outflags |= MMAN_nl; } font_push('B');