static void print_man_foot(struct termp *p, const void *arg) { const struct man_meta *meta; meta = (const struct man_meta *)arg; term_fontrepl(p, TERMFONT_NONE); term_vspace(p); term_vspace(p); term_vspace(p); p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->rmargin = p->maxrmargin - term_strlen(p, meta->date); p->offset = 0; /* term_strlen() can return zero. */ if (p->rmargin == p->maxrmargin) p->rmargin--; if (meta->source) term_word(p, meta->source); if (meta->source) term_word(p, ""); term_flushln(p); p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; term_word(p, meta->date); term_flushln(p); }
/* * This decides how to assert whitespace before any of the SYNOPSIS set * of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain * macro combos). */ static void synopsis_pre(struct termp *p, const struct mdoc_node *n) { /* * Obviously, if we're not in a SYNOPSIS or no prior macros * exist, do nothing. */ if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) return; /* * If we're the second in a pair of like elements, emit our * newline and return. UNLESS we're `Fo', `Fn', `Fn', in which * case we soldier on. */ if (n->prev->tok == n->tok && MDOC_Ft != n->tok && MDOC_Fo != n->tok && MDOC_Fn != n->tok) { term_newln(p); return; } /* * If we're one of the SYNOPSIS set and non-like pair-wise after * another (or Fn/Fo, which we've let slip through) then assert * vertical space, else only newline and move on. */ switch (n->prev->tok) { case (MDOC_Fd): /* FALLTHROUGH */ case (MDOC_Fn): /* FALLTHROUGH */ case (MDOC_Fo): /* FALLTHROUGH */ case (MDOC_In): /* FALLTHROUGH */ case (MDOC_Vt): term_vspace(p); break; case (MDOC_Ft): if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { term_vspace(p); break; } /* FALLTHROUGH */ default: term_newln(p); break; } }
static int pre_SS(DECL_ARGS) { int i; switch (n->type) { case MAN_BLOCK: mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); /* If following a prior empty `SS', no vspace. */ if (n->prev && MAN_SS == n->prev->tok) if (NULL == n->prev->body->child) break; if (NULL == n->prev) break; for (i = 0; i < mt->pardist; i++) term_vspace(p); break; case MAN_HEAD: term_fontrepl(p, TERMFONT_BOLD); p->offset = term_len(p, 3); break; case MAN_BODY: p->offset = mt->offset; break; default: break; } return(1); }
/* ARGSUSED */ 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); break; case (MDOC_HEAD): term_fontpush(p, TERMFONT_BOLD); break; case (MDOC_BODY): p->offset = term_len(p, p->defindent); if (SEC_AUTHORS == n->sec) p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); break; default: break; } return(1); }
static int termp_sh_pre(DECL_ARGS) { switch (n->type) { case MDOC_BLOCK: /* * 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); break; case MDOC_BODY: p->offset = term_len(p, p->defindent); if (SEC_AUTHORS == n->sec) p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); break; default: break; } return(1); }
/* ARGSUSED */ static int pre_SS(DECL_ARGS) { switch (n->type) { case (MAN_BLOCK): mt->lmargin = 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) if (NULL == n->prev->body->child) break; if (NULL == n->prev) break; term_vspace(p); break; case (MAN_HEAD): term_fontrepl(p, TERMFONT_BOLD); p->offset = term_len(p, HALFINDENT); break; case (MAN_BODY): p->offset = mt->offset; break; default: break; } return(1); }
/* ARGSUSED */ static int pre_sp(DECL_ARGS) { size_t i, len; if ((NULL == n->prev && n->parent)) { if (MAN_SS == n->parent->tok) return(0); if (MAN_SH == n->parent->tok) return(0); } switch (n->tok) { case (MAN_br): len = 0; break; default: len = n->child ? a2height(p, n->child->string) : 1; break; } if (0 == len) term_newln(p); for (i = 0; i < len; i++) term_vspace(p); return(0); }
/* ARGSUSED */ static int pre_SH(DECL_ARGS) { switch (n->type) { case (MAN_BLOCK): mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); /* If following a prior empty `SH', no vspace. */ if (n->prev && MAN_SH == n->prev->tok) if (NULL == n->prev->body->child) break; /* If the first macro, no vspae. */ if (NULL == n->prev) break; term_vspace(p); break; case (MAN_HEAD): term_fontrepl(p, TERMFONT_BOLD); p->offset = 0; break; case (MAN_BODY): p->offset = mt->offset; break; default: break; } return(1); }
static int termp_sp_pre(DECL_ARGS) { struct roffsu su; int i, len; switch (n->tok) { case MDOC_sp: if (n->child) { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } else len = 1; break; case MDOC_br: len = 0; break; default: len = 1; fn_prio = 0; break; } if (0 == len) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); return 0; }
static void post_HP(DECL_ARGS) { switch (n->type) { case ROFFT_BODY: term_newln(p); /* * Compatibility with a groff bug. * The .HP macro uses the undocumented .tag request * which causes a line break and cancels no-space * mode even if there isn't any output. */ if (n->child == NULL) term_vspace(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); p->trailspace = 0; p->offset = mt->offset; p->rmargin = p->maxrmargin; break; default: break; } }
static int termp_rs_pre(DECL_ARGS) { if (SEC_SEE_ALSO != n->sec) return 1; if (n->type == ROFFT_BLOCK && n->prev != NULL) term_vspace(p); return 1; }
/* ARGSUSED */ static int termp_rs_pre(DECL_ARGS) { if (SEC_SEE_ALSO != n->sec) return(1); if (MDOC_BLOCK == n->type && n->prev) term_vspace(p); return(1); }
static int pre_sp(DECL_ARGS) { char *s; size_t i, len; int neg; if ((NULL == n->prev && n->parent)) { switch (n->parent->tok) { case MAN_SH: /* FALLTHROUGH */ case MAN_SS: /* FALLTHROUGH */ case MAN_PP: /* FALLTHROUGH */ case MAN_LP: /* FALLTHROUGH */ case MAN_P: /* FALLTHROUGH */ return(0); default: break; } } neg = 0; switch (n->tok) { case MAN_br: len = 0; break; default: if (NULL == n->child) { len = 1; break; } s = n->child->string; if ('-' == *s) { neg = 1; s++; } len = a2height(p, s); break; } if (0 == len) term_newln(p); else if (neg) p->skipvsp += len; else for (i = 0; i < len; i++) term_vspace(p); return(0); }
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; term_fontrepl(p, TERMFONT_NONE); /* * Output the footer in new-groff style, that is, three columns * with the middle being the manual date and flanking columns * being the operating system: * * SYSTEM DATE SYSTEM */ term_vspace(p); p->offset = 0; 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; term_word(p, meta->os); term_flushln(p); p->offset = p->rmargin; sz = term_strlen(p, meta->os); p->rmargin = p->maxrmargin > sz ? p->maxrmargin - sz : 0; p->flags |= TERMP_NOSPACE; term_word(p, meta->date); term_flushln(p); p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->trailspace = 0; p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; term_word(p, meta->os); term_flushln(p); p->offset = 0; p->rmargin = p->maxrmargin; p->flags = 0; }
static void print_mdoc_foot(struct termp *p, const void *arg) { char buf[DATESIZ], os[BUFSIZ]; const struct mdoc_meta *m; m = (const struct mdoc_meta *)arg; term_fontrepl(p, TERMFONT_NONE); /* * Output the footer in new-groff style, that is, three columns * with the middle being the manual date and flanking columns * being the operating system: * * SYSTEM DATE SYSTEM */ time2a(m->date, buf, DATESIZ); strlcpy(os, m->os, BUFSIZ); term_vspace(p); p->offset = 0; p->rmargin = (p->maxrmargin - term_strlen(p, buf) + term_len(p, 1)) / 2; p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; term_word(p, os); term_flushln(p); p->offset = p->rmargin; p->rmargin = p->maxrmargin - term_strlen(p, os); p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; term_word(p, buf); term_flushln(p); p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; term_word(p, os); term_flushln(p); p->offset = 0; p->rmargin = p->maxrmargin; p->flags = 0; }
static int pre_sp(DECL_ARGS) { struct roffsu su; int i, len; if ((NULL == n->prev && n->parent)) { switch (n->parent->tok) { case MAN_SH: case MAN_SS: case MAN_PP: case MAN_LP: case MAN_P: return 0; default: break; } } if (n->tok == MAN_br) len = 0; else if (n->child == NULL) len = 1; else { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } if (len == 0) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); /* * Handle an explicit break request in the same way * as an overflowing line. */ if (p->flags & TERMP_BRIND) { p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); } return 0; }
/* * 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, * too. */ static void print_bvspace(struct termp *p, const struct roff_node *bl, const struct roff_node *n) { const struct roff_node *nn; assert(n); term_newln(p); if (MDOC_Bd == bl->tok && bl->norm->Bd.comp) return; if (MDOC_Bl == bl->tok && bl->norm->Bl.comp) return; /* Do not vspace directly after Ss/Sh. */ nn = n; while (nn->prev == NULL) { do { nn = nn->parent; if (nn->type == ROFFT_ROOT) return; } while (nn->type != ROFFT_BLOCK); if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss) return; if (nn->tok == MDOC_It && nn->parent->parent->norm->Bl.type != LIST_item) break; } /* A `-column' does not assert vspace within the list. */ if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type) if (n->prev && MDOC_It == n->prev->tok) return; /* A `-diag' without body does not vspace. */ if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type) if (n->prev && MDOC_It == n->prev->tok) { assert(n->prev->body); if (NULL == n->prev->body->child) return; } term_vspace(p); }
/* * Printing leading vertical space before a block. * This is used for the paragraph macros. * The rules are pretty simple, since there's very little nesting going * on here. Basically, if we're the first within another block (SS/SH), * then don't emit vertical space. If we are (RS), then do. If not the * first, print it. */ static void print_bvspace(struct termp *p, const struct man_node *n) { term_newln(p); if (n->body && n->body->child) if (MAN_TBL == n->body->child->type) return; if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) if (NULL == n->prev) return; term_vspace(p); }
/* * 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, * too. */ static void print_bvspace(struct termp *p, const struct mdoc_node *bl, const struct mdoc_node *n) { const struct mdoc_node *nn; assert(n); term_newln(p); if (MDOC_Bd == bl->tok && bl->norm->Bd.comp) return; if (MDOC_Bl == bl->tok && bl->norm->Bl.comp) return; /* 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) return; if (MDOC_Sh == nn->tok) return; if (NULL == nn->prev) continue; break; } /* A `-column' does not assert vspace within the list. */ if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type) if (n->prev && MDOC_It == n->prev->tok) return; /* A `-diag' without body does not vspace. */ if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type) if (n->prev && MDOC_It == n->prev->tok) { assert(n->prev->body); if (NULL == n->prev->body->child) return; } term_vspace(p); }
static int pre_SS(DECL_ARGS) { int i; switch (n->type) { case ROFFT_BLOCK: mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); /* * No vertical space before the first subsection * and after an empty subsection. */ do { n = n->prev; } while (n != NULL && n->tok != TOKEN_NONE && termacts[n->tok].flags & MAN_NOTEXT); if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) term_vspace(p); break; case ROFFT_HEAD: term_fontrepl(p, TERMFONT_BOLD); p->offset = term_len(p, 3); p->rmargin = mt->offset; p->trailspace = mt->offset; p->flags |= TERMP_NOBREAK | TERMP_BRIND; break; case ROFFT_BODY: p->offset = mt->offset; p->rmargin = p->maxrmargin; p->trailspace = 0; p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND); break; default: break; } return 1; }
static void print_bvspace(struct termp *p, const struct man_node *n) { term_newln(p); if (n->body && n->body->child && MAN_TBL == n->body->child->type) return; if (NULL == n->prev) return; if (MAN_SS == n->prev->tok) return; if (MAN_SH == n->prev->tok) return; term_vspace(p); }
/* * Printing leading vertical space before a block. * This is used for the paragraph macros. * The rules are pretty simple, since there's very little nesting going * on here. Basically, if we're the first within another block (SS/SH), * then don't emit vertical space. If we are (RS), then do. If not the * first, print it. */ static void print_bvspace(struct termp *p, const struct man_node *n, int pardist) { int i; term_newln(p); if (n->body && n->body->child) if (MAN_TBL == n->body->child->type) return; if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok) if (NULL == n->prev) return; for (i = 0; i < pardist; i++) term_vspace(p); }
/* * Printing leading vertical space before a block. * This is used for the paragraph macros. * The rules are pretty simple, since there's very little nesting going * on here. Basically, if we're the first within another block (SS/SH), * then don't emit vertical space. If we are (RS), then do. If not the * first, print it. */ static void print_bvspace(struct termp *p, const struct roff_node *n, int pardist) { int i; term_newln(p); if (n->body && n->body->child) if (n->body->child->type == ROFFT_TBL) return; if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS) if (NULL == n->prev) return; for (i = 0; i < pardist; i++) term_vspace(p); }
static int pre_sp(DECL_ARGS) { struct roffsu su; int i, len; if ((NULL == n->prev && n->parent)) { switch (n->parent->tok) { case MAN_SH: /* FALLTHROUGH */ case MAN_SS: /* FALLTHROUGH */ case MAN_PP: /* FALLTHROUGH */ case MAN_LP: /* FALLTHROUGH */ case MAN_P: /* FALLTHROUGH */ return(0); default: break; } } if (n->tok == MAN_br) len = 0; else if (n->child == NULL) len = 1; else { if ( ! a2roffsu(n->child->string, &su, SCALE_VS)) su.scale = 1.0; len = term_vspan(p, &su); } if (len == 0) term_newln(p); else if (len < 0) p->skipvsp -= len; else for (i = 0; i < len; i++) term_vspace(p); return(0); }
/* ARGSUSED */ static int termp_ss_pre(DECL_ARGS) { switch (n->type) { case (MDOC_BLOCK): term_newln(p); if (n->prev) term_vspace(p); break; case (MDOC_HEAD): term_fontpush(p, TERMFONT_BOLD); p->offset = term_len(p, (p->defindent+1)/2); break; default: break; } return(1); }
static void roff_term_pre_sp(ROFF_TERM_ARGS) { struct roffsu su; int len; if (n->child != NULL) { if (a2roffsu(n->child->string, &su, SCALE_VS) == NULL) su.scale = 1.0; len = term_vspan(p, &su); } else len = 1; if (len < 0) p->skipvsp -= len; else while (len--) term_vspace(p); roff_term_pre_br(p, n); }
void terminal_mdoc(void *arg, const struct mdoc *mdoc) { const struct mdoc_meta *meta; struct mdoc_node *n; struct termp *p; p = (struct termp *)arg; p->overstep = 0; p->rmargin = p->maxrmargin = p->defrmargin; p->tabwidth = term_len(p, 5); n = mdoc_node(mdoc)->child; meta = mdoc_meta(mdoc); if (p->synopsisonly) { while (n != NULL) { if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) { if (n->child->next->child != NULL) print_mdoc_nodelist(p, NULL, meta, n->child->next->child); term_newln(p); break; } n = n->next; } } else { if (p->defindent == 0) p->defindent = 5; term_begin(p, print_mdoc_head, print_mdoc_foot, meta); if (n != NULL) { if (n->tok != MDOC_Sh) term_vspace(p); print_mdoc_nodelist(p, NULL, meta, n); } term_end(p); } }
static int pre_SH(DECL_ARGS) { int i; switch (n->type) { case MAN_BLOCK: mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); /* * No vertical space before the first section * and after an empty section. */ do { n = n->prev; } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT); if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) term_vspace(p); break; case MAN_HEAD: term_fontrepl(p, TERMFONT_BOLD); p->offset = 0; break; case MAN_BODY: p->offset = mt->offset; break; default: break; } return(1); }
/* ARGSUSED */ 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); break; case (MDOC_HEAD): term_fontpush(p, TERMFONT_BOLD); break; case (MDOC_BODY): p->offset = term_len(p, INDENT); break; default: break; } return(1); }
/* ARGSUSED */ static int termp_sp_pre(DECL_ARGS) { size_t i, len; switch (n->tok) { case (MDOC_sp): len = n->child ? a2height(p, n->child->string) : 1; break; case (MDOC_br): len = 0; break; default: len = 1; break; } if (0 == len) term_newln(p); for (i = 0; i < len; i++) term_vspace(p); return(0); }