static int a2width(const struct termp *p, const char *v) { struct roffsu su; if (a2roffsu(v, &su, SCALE_MAX) < 2) { SCALE_HS_INIT(&su, term_strlen(p, v)); su.scale /= term_strlen(p, "0"); } return term_hspan(p, &su) / 24; }
static int termp_nm_pre(DECL_ARGS) { const char *cp; if (n->type == ROFFT_BLOCK) { p->flags |= TERMP_PREKEEP; return 1; } if (n->type == ROFFT_BODY) { if (NULL == n->child) return 0; p->flags |= TERMP_NOSPACE; cp = NULL; if (n->prev->child != NULL) cp = n->prev->child->string; if (cp == NULL) cp = meta->name; if (cp == NULL) p->offset += term_len(p, 6); else p->offset += term_len(p, 1) + term_strlen(p, cp); return 1; } if (NULL == n->child && NULL == meta->name) return 0; if (n->type == ROFFT_HEAD) synopsis_pre(p, n->parent); if (n->type == ROFFT_HEAD && NULL != n->next && NULL != n->next->child) { p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_BRIND; p->trailspace = 1; p->rmargin = p->offset + term_len(p, 1); if (NULL == n->child) { p->rmargin += term_strlen(p, meta->name); } else if (n->child->type == ROFFT_TEXT) { p->rmargin += term_strlen(p, n->child->string); if (n->child->next) p->flags |= TERMP_HANG; } else { p->rmargin += term_len(p, 5); p->flags |= TERMP_HANG; } } term_fontpush(p, TERMFONT_BOLD); if (NULL == n->child) term_word(p, meta->name); return 1; }
static size_t a2width(const struct termp *p, const char *v) { struct roffsu su; assert(v); 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)); }
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; }
/* ARGSUSED */ static int termp_nm_pre(DECL_ARGS) { if (MDOC_BLOCK == n->type) { p->flags |= TERMP_PREKEEP; return(1); } if (MDOC_BODY == n->type) { if (NULL == n->child) return(0); p->flags |= TERMP_NOSPACE; p->offset += term_len(p, 1) + (NULL == n->prev->child ? term_strlen(p, meta->name) : MDOC_TEXT == n->prev->child->type ? term_strlen(p, n->prev->child->string) : term_len(p, 5)); return(1); } if (NULL == n->child && NULL == meta->name) return(0); if (MDOC_HEAD == n->type) synopsis_pre(p, n->parent); if (MDOC_HEAD == n->type && n->next->child) { p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->trailspace = 1; p->rmargin = p->offset + term_len(p, 1); if (NULL == n->child) { p->rmargin += term_strlen(p, meta->name); } else if (MDOC_TEXT == n->child->type) { p->rmargin += term_strlen(p, n->child->string); if (n->child->next) p->flags |= TERMP_HANG; } else { p->rmargin += term_len(p, 5); p->flags |= TERMP_HANG; } } term_fontpush(p, TERMFONT_BOLD); if (NULL == n->child) term_word(p, meta->name); return(1); }
static void tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { size_t len, padl, padr; assert(dp->string); len = term_strlen(tp, dp->string); padr = col->width > len ? col->width - len : 0; padl = 0; switch (dp->layout->pos) { case (TBL_CELL_LONG): padl = term_len(tp, 1); padr = padr > padl ? padr - padl : 0; break; case (TBL_CELL_CENTRE): if (2 > padr) break; padl = padr / 2; padr -= padl; break; case (TBL_CELL_RIGHT): padl = padr; padr = 0; break; default: break; } tbl_char(tp, ASCII_NBRSP, padl); term_word(tp, dp->string); tbl_char(tp, ASCII_NBRSP, padr); }
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); }
static void tbl_number(struct termp *tp, const struct tbl *tbl, const struct tbl_dat *dp, const struct roffcol *col) { char *cp; char buf[2]; const char *str; size_t sz, psz, ssz, d, padl; int i; /* * See calc_data_number(). Left-pad by taking the offset of our * and the maximum decimal; right-pad by the remaining amount. */ str = dp && dp->string ? dp->string : ""; sz = term_strlen(tp, str); buf[0] = tbl->decimal; buf[1] = '\0'; psz = term_strlen(tp, buf); if (NULL != (cp = strchr(str, tbl->decimal))) { buf[1] = '\0'; for (ssz = 0, i = 0; cp != &str[i]; i++) { buf[0] = str[i]; ssz += term_strlen(tp, buf); } d = ssz + psz; } else d = sz + psz; sz += term_len(tp, 2); d += term_len(tp, 1); padl = col->decimal - d; tbl_char(tp, ASCII_NBRSP, padl); term_word(tp, str); tbl_char(tp, ASCII_NBRSP, col->width - sz - padl); }
static size_t a2height(const struct termp *p, const char *cp) { struct roffsu su; if ( ! a2roffsu(cp, &su, SCALE_VS)) SCALE_VS_INIT(&su, term_strlen(p, cp)); return(term_vspan(p, &su)); }
static void tbl_number(struct termp *tp, const struct tbl_opts *opts, const struct tbl_dat *dp, const struct roffcol *col) { char *cp; char buf[2]; size_t sz, psz, ssz, d, padl; int i; /* * See calc_data_number(). Left-pad by taking the offset of our * and the maximum decimal; right-pad by the remaining amount. */ assert(dp->string); sz = term_strlen(tp, dp->string); buf[0] = opts->decimal; buf[1] = '\0'; psz = term_strlen(tp, buf); if (NULL != (cp = strrchr(dp->string, opts->decimal))) { buf[1] = '\0'; for (ssz = 0, i = 0; cp != &dp->string[i]; i++) { buf[0] = dp->string[i]; ssz += term_strlen(tp, buf); } d = ssz + psz; } else d = sz + psz; padl = col->decimal - d; tbl_char(tp, ASCII_NBRSP, padl); term_word(tp, dp->string); if (col->width > sz + padl) tbl_char(tp, ASCII_NBRSP, col->width - sz - padl); }
static void tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { size_t padl, padr, ssz; enum tbl_cellt pos; const char *str; padl = padr = 0; pos = dp && dp->layout ? dp->layout->pos : TBL_CELL_LEFT; str = dp && dp->string ? dp->string : ""; ssz = term_len(tp, 1); switch (pos) { case (TBL_CELL_LONG): padl = ssz; padr = col->width - term_strlen(tp, str) - ssz; break; case (TBL_CELL_CENTRE): padl = col->width - term_strlen(tp, str); if (padl % 2) padr++; padl /= 2; padr += padl; break; case (TBL_CELL_RIGHT): padl = col->width - term_strlen(tp, str); break; default: padr = col->width - term_strlen(tp, str); break; } tbl_char(tp, ASCII_NBRSP, padl); term_word(tp, str); tbl_char(tp, ASCII_NBRSP, padr); }
static void tbl_char(struct termp *tp, char c, size_t len) { size_t i, sz; char cp[2]; cp[0] = c; cp[1] = '\0'; sz = term_strlen(tp, cp); for (i = 0; i < len; i += sz) term_word(tp, cp); }
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)); return(term_hspan(p, &su)); }
static void tbl_literal(struct termp *tp, const struct tbl_dat *dp, const struct roffcol *col) { struct tbl_head *hp; size_t width, len, padl, padr; int spans; assert(dp->string); len = term_strlen(tp, dp->string); hp = dp->layout->head->next; width = col->width; for (spans = dp->spans; spans--; hp = hp->next) width += tp->tbl.cols[hp->ident].width + 3; padr = width > len ? width - len : 0; padl = 0; switch (dp->layout->pos) { case TBL_CELL_LONG: padl = term_len(tp, 1); padr = padr > padl ? padr - padl : 0; break; case TBL_CELL_CENTRE: if (2 > padr) break; padl = padr / 2; padr -= padl; break; case TBL_CELL_RIGHT: padl = padr; padr = 0; break; default: break; } tbl_char(tp, ASCII_NBRSP, padl); term_word(tp, dp->string); tbl_char(tp, ASCII_NBRSP, padr); }
static void print_man_foot(struct termp *p, const struct roff_meta *meta) { char *title; size_t datelen, titlen; assert(meta->title); assert(meta->msec); assert(meta->date); term_fontrepl(p, TERMFONT_NONE); if (meta->hasbody) term_vspace(p); /* * Temporary, undocumented option to imitate mdoc(7) output. * In the bottom right corner, use the operating system * instead of the title. */ if ( ! p->mdocstyle) { if (meta->hasbody) { term_vspace(p); term_vspace(p); } mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec); } else if (meta->os) { title = mandoc_strdup(meta->os); } else { title = mandoc_strdup(""); } datelen = term_strlen(p, meta->date); /* Bottom left corner: operating system. */ p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->trailspace = 1; p->offset = 0; p->rmargin = p->maxrmargin > datelen ? (p->maxrmargin + term_len(p, 1) - datelen) / 2 : 0; if (meta->os) term_word(p, meta->os); term_flushln(p); /* At the bottom in the middle: manual date. */ p->offset = p->rmargin; titlen = term_strlen(p, title); p->rmargin = p->maxrmargin > titlen ? p->maxrmargin - titlen : 0; p->flags |= TERMP_NOSPACE; term_word(p, meta->date); term_flushln(p); /* Bottom right corner: manual title and section. */ p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; p->trailspace = 0; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); free(title); }
static void print_man_head(struct termp *p, const struct roff_meta *meta) { const char *volume; char *title; size_t vollen, titlen; assert(meta->title); assert(meta->msec); volume = NULL == meta->vol ? "" : meta->vol; vollen = term_strlen(p, volume); /* Top left corner: manual title and section. */ mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec); titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; p->trailspace = 1; p->offset = 0; p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ? (p->maxrmargin - vollen + term_len(p, 1)) / 2 : vollen < p->maxrmargin ? p->maxrmargin - vollen : 0; term_word(p, title); term_flushln(p); /* At the top in the middle: manual volume. */ p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->offset + vollen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; term_word(p, volume); term_flushln(p); /* Top right corner: title and section, again. */ p->flags &= ~TERMP_NOBREAK; p->trailspace = 0; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); } p->flags &= ~TERMP_NOSPACE; p->offset = 0; p->rmargin = p->maxrmargin; /* * Groff prints three blank lines before the content. * Do the same, except in the temporary, undocumented * mode imitating mdoc(7) output. */ term_vspace(p); if ( ! p->mdocstyle) { term_vspace(p); term_vspace(p); } free(title); }
static void print_mdoc_head(struct termp *p, const void *arg) { char buf[BUFSIZ], title[BUFSIZ]; size_t buflen, titlen; const struct mdoc_meta *meta; meta = (const struct mdoc_meta *)arg; /* * The header is strange. It has three components, which are * really two with the first duplicated. It goes like this: * * IDENTIFIER TITLE IDENTIFIER * * The IDENTIFIER is NAME(SECTION), which is the command-name * (if given, or "unknown" if not) followed by the manual page * section. These are given in `Dt'. The TITLE is a free-form * string depending on the manual volume. If not specified, it * switches on the manual section. */ p->offset = 0; p->rmargin = p->maxrmargin; assert(meta->vol); strlcpy(buf, meta->vol, BUFSIZ); buflen = term_strlen(p, buf); if (meta->arch) { strlcat(buf, " (", BUFSIZ); strlcat(buf, meta->arch, BUFSIZ); strlcat(buf, ")", BUFSIZ); } snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec); titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; p->trailspace = 1; 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; term_word(p, title); term_flushln(p); p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; term_word(p, buf); term_flushln(p); p->flags &= ~TERMP_NOBREAK; p->trailspace = 0; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); } p->flags &= ~TERMP_NOSPACE; p->offset = 0; p->rmargin = p->maxrmargin; }
static void print_mdoc_head(struct termp *p, const struct roff_meta *meta) { char *volume, *title; size_t vollen, titlen; /* * The header is strange. It has three components, which are * really two with the first duplicated. It goes like this: * * IDENTIFIER TITLE IDENTIFIER * * The IDENTIFIER is NAME(SECTION), which is the command-name * (if given, or "unknown" if not) followed by the manual page * section. These are given in `Dt'. The TITLE is a free-form * string depending on the manual volume. If not specified, it * switches on the manual section. */ assert(meta->vol); if (NULL == meta->arch) volume = mandoc_strdup(meta->vol); else mandoc_asprintf(&volume, "%s (%s)", meta->vol, meta->arch); vollen = term_strlen(p, volume); if (NULL == meta->msec) title = mandoc_strdup(meta->title); else mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec); titlen = term_strlen(p, title); p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; p->trailspace = 1; p->offset = 0; p->rmargin = 2 * (titlen+1) + vollen < p->maxrmargin ? (p->maxrmargin - vollen + term_len(p, 1)) / 2 : vollen < p->maxrmargin ? p->maxrmargin - vollen : 0; term_word(p, title); term_flushln(p); p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->offset + vollen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; term_word(p, volume); term_flushln(p); p->flags &= ~TERMP_NOBREAK; p->trailspace = 0; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); } p->flags &= ~TERMP_NOSPACE; p->offset = 0; p->rmargin = p->maxrmargin; free(title); free(volume); }
static int termp_bd_pre(DECL_ARGS) { size_t tabwidth, lm, len, rm, rmax; struct roff_node *nn; int offset; if (n->type == ROFFT_BLOCK) { print_bvspace(p, n, n); return 1; } else if (n->type == ROFFT_HEAD) return 0; /* 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 { offset = a2width(p, n->norm->Bd.offs); if (offset < 0 && (size_t)(-offset) > p->offset) p->offset = 0; else if (offset < SHRT_MAX) p->offset += offset; } /* * If -ragged or -filled are specified, the block does nothing * but change the indentation. If -unfilled or -literal are * specified, text is printed exactly as entered in the display: * for macro lines, a newline is appended to the line. Blank * lines are allowed. */ if (DISP_literal != n->norm->Bd.type && DISP_unfilled != n->norm->Bd.type && DISP_centered != n->norm->Bd.type) return 1; tabwidth = p->tabwidth; if (DISP_literal == n->norm->Bd.type) p->tabwidth = term_len(p, 8); lm = p->offset; rm = p->rmargin; rmax = p->maxrmargin; p->rmargin = p->maxrmargin = TERM_MAXMARGIN; for (nn = n->child; nn; nn = nn->next) { if (DISP_centered == n->norm->Bd.type) { if (nn->type == ROFFT_TEXT) { len = term_strlen(p, nn->string); p->offset = len >= rm ? 0 : lm + len >= rm ? rm - len : (lm + rm - len) / 2; } else p->offset = lm; } print_mdoc_node(p, pair, meta, nn); /* * If the printed node flushes its own line, then we * needn't do it here as well. This is hacky, but the * notion of selective eoln whitespace is pretty dumb * anyway, so don't sweat it. */ switch (nn->tok) { case MDOC_Sm: case MDOC_br: case MDOC_sp: case MDOC_Bl: case MDOC_D1: case MDOC_Dl: case MDOC_Lp: case MDOC_Pp: continue; default: break; } if (p->flags & TERMP_NONEWLINE || (nn->next && ! (nn->next->flags & MDOC_LINE))) continue; term_flushln(p); p->flags |= TERMP_NOSPACE; } p->tabwidth = tabwidth; p->rmargin = rm; p->maxrmargin = rmax; return 0; }
static void print_man_foot(struct termp *p, const void *arg) { char title[BUFSIZ]; size_t datelen; const struct man_meta *meta; meta = (const struct man_meta *)arg; assert(meta->title); assert(meta->msec); assert(meta->date); term_fontrepl(p, TERMFONT_NONE); term_vspace(p); /* * Temporary, undocumented option to imitate mdoc(7) output. * In the bottom right corner, use the source instead of * the title. */ if ( ! p->mdocstyle) { term_vspace(p); term_vspace(p); snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec); } else if (meta->source) { strlcpy(title, meta->source, BUFSIZ); } else { title[0] = '\0'; } datelen = term_strlen(p, meta->date); /* Bottom left corner: manual source. */ p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->offset = 0; p->rmargin = (p->maxrmargin - datelen + term_len(p, 1)) / 2; if (meta->source) term_word(p, meta->source); term_flushln(p); /* At the bottom in the middle: manual date. */ p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin - term_strlen(p, title); if (p->offset + datelen >= p->rmargin) p->rmargin = p->offset + datelen; term_word(p, meta->date); term_flushln(p); /* Bottom right corner: manual title and section. */ p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); }
static void print_man_head(struct termp *p, const void *arg) { char buf[BUFSIZ], title[BUFSIZ]; size_t buflen, titlen; const struct man_meta *m; m = (const struct man_meta *)arg; assert(m->title); assert(m->msec); if (m->vol) strlcpy(buf, m->vol, BUFSIZ); else buf[0] = '\0'; buflen = term_strlen(p, buf); /* Top left corner: manual title and section. */ 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; term_word(p, title); term_flushln(p); /* At the top in the middle: manual volume. */ p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; term_word(p, buf); term_flushln(p); /* Top right corner: title and section, again. */ p->flags &= ~TERMP_NOBREAK; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; term_word(p, title); term_flushln(p); } p->flags &= ~TERMP_NOSPACE; p->offset = 0; p->rmargin = p->maxrmargin; /* * Groff prints three blank lines before the content. * Do the same, except in the temporary, undocumented * mode imitating mdoc(7) output. */ term_vspace(p); if ( ! p->mdocstyle) { term_vspace(p); term_vspace(p); } }
static size_t term_tbl_strlen(const char *p, void *arg) { return(term_strlen((const struct termp *)arg, p)); }
static void print_man_head(struct termp *p, const void *arg) { char buf[BUFSIZ], title[BUFSIZ]; size_t buflen, titlen; const struct man_meta *m; m = (const struct man_meta *)arg; /* * Note that old groff would spit out some spaces before the * header. We discontinue this strange behaviour, but at one * point we did so here. */ p->rmargin = p->maxrmargin; p->offset = 0; buf[0] = title[0] = '\0'; if (m->vol) strlcpy(buf, m->vol, BUFSIZ); buflen = term_strlen(p, buf); snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec); titlen = term_strlen(p, title); 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->offset = p->rmargin; p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin; term_word(p, buf); term_flushln(p); p->flags &= ~TERMP_NOBREAK; if (p->rmargin + titlen <= p->maxrmargin) { p->flags |= TERMP_NOLPAD | 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; /* * Groff likes to have some leading spaces before content. Well * that's fine by me. */ term_vspace(p); term_vspace(p); term_vspace(p); }