=================================================================== RCS file: /cvs/mandoc/man_term.c,v retrieving revision 1.114 retrieving revision 1.121 diff -u -p -r1.114 -r1.121 --- mandoc/man_term.c 2011/07/21 11:34:53 1.114 +++ mandoc/man_term.c 2011/09/21 09:57:13 1.121 @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.114 2011/07/21 11:34:53 kristaps Exp $ */ +/* $Id: man_term.c,v 1.121 2011/09/21 09:57:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -33,29 +33,19 @@ #include "term.h" #include "main.h" -#define INDENT 7 -#define HALFINDENT 3 +#define INDENT 7 /* fixed-width char full-indent */ +#define HALFINDENT 3 /* fixed-width char half-indent */ +#define MAXMARGINS 64 /* maximum number of indented scopes */ /* FIXME: have PD set the default vspace width. */ struct mtermp { int fl; #define MANT_LITERAL (1 << 0) - /* - * Default amount to indent the left margin after leading text - * has been printed (e.g., `HP' left-indent, `TP' and `IP' body - * indent). This needs to be saved because `HP' and so on, if - * not having a specified value, must default. - * - * Note that this is the indentation AFTER the left offset, so - * the total offset is usually offset + lmargin. - */ - size_t lmargin; - /* - * The default offset, i.e., the amount between any text and the - * page boundary. - */ - size_t offset; + size_t lmargin[MAXMARGINS]; /* margins (incl. visible page) */ + int lmargincur; /* index of current margin */ + int lmarginsz; /* actual number of nested margins */ + size_t offset; /* default offset to visible page */ }; #define DECL_ARGS struct termp *p, \ @@ -164,8 +154,9 @@ terminal_man(void *arg, const struct man *man) term_begin(p, print_man_head, print_man_foot, m); p->flags |= TERMP_NOSPACE; - mt.fl = 0; - mt.lmargin = term_len(p, INDENT); + memset(&mt, 0, sizeof(struct mtermp)); + + mt.lmargin[mt.lmargincur] = term_len(p, INDENT); mt.offset = term_len(p, INDENT); if (n->child) @@ -254,6 +245,18 @@ pre_literal(DECL_ARGS) else mt->fl &= ~MANT_LITERAL; + /* + * Unlike .IP and .TP, .HP does not have a HEAD. + * So in case a second call to term_flushln() is needed, + * indentation has to be set up explicitly. + */ + if (MAN_HP == n->parent->tok && p->rmargin < p->maxrmargin) { + p->offset = p->rmargin; + p->rmargin = p->maxrmargin; + p->flags &= ~(TERMP_NOBREAK | TERMP_TWOSPACE); + p->flags |= TERMP_NOSPACE; + } + return(0); } @@ -440,7 +443,7 @@ pre_sp(DECL_ARGS) static int pre_HP(DECL_ARGS) { - size_t len; + size_t len, one; int ival; const struct man_node *nn; @@ -456,7 +459,7 @@ pre_HP(DECL_ARGS) return(0); } - len = mt->lmargin; + len = mt->lmargin[mt->lmargincur]; ival = -1; /* Calculate offset. */ @@ -465,14 +468,15 @@ pre_HP(DECL_ARGS) if ((ival = a2width(p, nn->string)) >= 0) len = (size_t)ival; - if (0 == len) - len = term_len(p, 1); + one = term_len(p, 1); + if (len < one) + len = one; p->offset = mt->offset; p->rmargin = mt->offset + len; if (ival >= 0) - mt->lmargin = (size_t)ival; + mt->lmargin[mt->lmargincur] = (size_t)ival; return(1); } @@ -507,7 +511,7 @@ pre_PP(DECL_ARGS) switch (n->type) { case (MAN_BLOCK): - mt->lmargin = term_len(p, INDENT); + mt->lmargin[mt->lmargincur] = term_len(p, INDENT); print_bvspace(p, n); break; default: @@ -529,7 +533,6 @@ pre_IP(DECL_ARGS) switch (n->type) { case (MAN_BODY): - p->flags |= TERMP_NOLPAD; p->flags |= TERMP_NOSPACE; break; case (MAN_HEAD): @@ -542,7 +545,7 @@ pre_IP(DECL_ARGS) return(1); } - len = mt->lmargin; + len = mt->lmargin[mt->lmargincur]; ival = -1; /* Calculate the offset from the optional second argument. */ @@ -563,7 +566,7 @@ pre_IP(DECL_ARGS) break; /* Set the saved left-margin. */ - mt->lmargin = (size_t)ival; + mt->lmargin[mt->lmargincur] = (size_t)ival; savelit = MANT_LITERAL & mt->fl; mt->fl &= ~MANT_LITERAL; @@ -600,7 +603,6 @@ post_IP(DECL_ARGS) break; case (MAN_BODY): term_newln(p); - p->flags &= ~TERMP_NOLPAD; break; default: break; @@ -621,7 +623,6 @@ pre_TP(DECL_ARGS) p->flags |= TERMP_NOBREAK; break; case (MAN_BODY): - p->flags |= TERMP_NOLPAD; p->flags |= TERMP_NOSPACE; break; case (MAN_BLOCK): @@ -631,18 +632,15 @@ pre_TP(DECL_ARGS) return(1); } - len = (size_t)mt->lmargin; + len = (size_t)mt->lmargin[mt->lmargincur]; ival = -1; /* Calculate offset. */ - if (NULL != (nn = n->parent->head->child)) { - while (nn && MAN_TEXT != nn->type) - nn = nn->next; - if (nn && nn->next) + if (NULL != (nn = n->parent->head->child)) + if (nn->string && nn->parent->line == nn->line) if ((ival = a2width(p, nn->string)) >= 0) len = (size_t)ival; - } switch (n->type) { case (MAN_HEAD): @@ -663,9 +661,8 @@ pre_TP(DECL_ARGS) if (savelit) mt->fl |= MANT_LITERAL; - if (ival >= 0) - mt->lmargin = (size_t)ival; + mt->lmargin[mt->lmargincur] = (size_t)ival; return(0); case (MAN_BODY): @@ -694,7 +691,6 @@ post_TP(DECL_ARGS) break; case (MAN_BODY): term_newln(p); - p->flags &= ~TERMP_NOLPAD; break; default: break; @@ -710,7 +706,7 @@ pre_SS(DECL_ARGS) switch (n->type) { case (MAN_BLOCK): mt->fl &= ~MANT_LITERAL; - mt->lmargin = term_len(p, INDENT); + mt->lmargin[mt->lmargincur] = term_len(p, INDENT); mt->offset = term_len(p, INDENT); /* If following a prior empty `SS', no vspace. */ if (n->prev && MAN_SS == n->prev->tok) @@ -761,7 +757,7 @@ pre_SH(DECL_ARGS) switch (n->type) { case (MAN_BLOCK): mt->fl &= ~MANT_LITERAL; - mt->lmargin = term_len(p, INDENT); + mt->lmargin[mt->lmargincur] = term_len(p, INDENT); mt->offset = term_len(p, INDENT); /* If following a prior empty `SH', no vspace. */ if (n->prev && MAN_SH == n->prev->tok) @@ -828,8 +824,13 @@ pre_RS(DECL_ARGS) sz = (size_t)ival; mt->offset += sz; - p->offset = mt->offset; + p->rmargin = p->maxrmargin; + p->offset = mt->offset < p->rmargin ? mt->offset : p->rmargin; + if (++mt->lmarginsz < MAXMARGINS) + mt->lmargincur = mt->lmarginsz; + + mt->lmargin[mt->lmargincur] = mt->lmargin[mt->lmargincur - 1]; return(1); } @@ -858,6 +859,9 @@ post_RS(DECL_ARGS) mt->offset = mt->offset < sz ? 0 : mt->offset - sz; p->offset = mt->offset; + + if (--mt->lmarginsz < MAXMARGINS) + mt->lmargincur = mt->lmarginsz; } static void @@ -888,7 +892,7 @@ print_man_node(DECL_ARGS) * -man doesn't have nested macros, we don't need to be * more specific than this. */ - if (MANT_LITERAL & mt->fl && + if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) && (NULL == n->next || n->next->line > n->line)) { rm = p->rmargin; @@ -896,7 +900,6 @@ print_man_node(DECL_ARGS) p->rmargin = p->maxrmargin = TERM_MAXMARGIN; p->flags |= TERMP_NOSPACE; term_flushln(p); - p->flags &= ~TERMP_NOLPAD; p->rmargin = rm; p->maxrmargin = rmax; } @@ -905,7 +908,7 @@ print_man_node(DECL_ARGS) p->flags |= TERMP_SENTENCE; return; case (MAN_EQN): - /*term_word(p, n->eqn->data);*/ + term_eqn(p, n->eqn); return; case (MAN_TBL): /* @@ -978,7 +981,7 @@ print_man_foot(struct termp *p, const void *arg) term_word(p, ""); term_flushln(p); - p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; + p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; @@ -1003,9 +1006,9 @@ print_man_head(struct termp *p, const void *arg) * point we did so here. */ + p->offset = 0; p->rmargin = p->maxrmargin; - p->offset = 0; buf[0] = title[0] = '\0'; if (m->vol) @@ -1015,17 +1018,17 @@ print_man_head(struct termp *p, const void *arg) snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec); titlen = term_strlen(p, title); + p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; p->offset = 0; p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ? (p->maxrmargin - term_strlen(p, buf) + term_len(p, 1)) / 2 : p->maxrmargin - buflen; - p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; term_word(p, title); term_flushln(p); - p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; + p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; @@ -1035,16 +1038,16 @@ print_man_head(struct termp *p, const void *arg) p->flags &= ~TERMP_NOBREAK; if (p->rmargin + titlen <= p->maxrmargin) { - p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; + p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); } - p->rmargin = p->maxrmargin; - p->offset = 0; p->flags &= ~TERMP_NOSPACE; + p->offset = 0; + p->rmargin = p->maxrmargin; /* * Groff likes to have some leading spaces before content. Well