static void print_mdoc_node(DECL_ARGS) { int chld; struct termpair npair; size_t offset, rmargin; chld = 1; offset = p->offset; rmargin = p->rmargin; n->flags &= ~MDOC_ENDED; n->prev_font = p->fonti; memset(&npair, 0, sizeof(struct termpair)); npair.ppair = pair; /* * Keeps only work until the end of a line. If a keep was * invoked in a prior line, revert it to PREKEEP. */ if (p->flags & TERMP_KEEP && n->flags & MDOC_LINE) { p->flags &= ~TERMP_KEEP; p->flags |= TERMP_PREKEEP; } /* * After the keep flags have been set up, we may now * produce output. Note that some pre-handlers do so. */ switch (n->type) { case ROFFT_TEXT: if (' ' == *n->string && MDOC_LINE & n->flags) term_newln(p); if (MDOC_DELIMC & n->flags) p->flags |= TERMP_NOSPACE; term_word(p, n->string); if (MDOC_DELIMO & n->flags) p->flags |= TERMP_NOSPACE; break; case ROFFT_EQN: if ( ! (n->flags & MDOC_LINE)) p->flags |= TERMP_NOSPACE; term_eqn(p, n->eqn); if (n->next != NULL && ! (n->next->flags & MDOC_LINE)) p->flags |= TERMP_NOSPACE; break; case ROFFT_TBL: if (p->tbl.cols == NULL) term_newln(p); term_tbl(p, n->span); break; default: if (termacts[n->tok].pre && (n->end == ENDBODY_NOT || n->child != NULL)) chld = (*termacts[n->tok].pre) (p, &npair, meta, n); break; } if (chld && n->child) print_mdoc_nodelist(p, &npair, meta, n->child); term_fontpopq(p, (ENDBODY_NOT == n->end ? n : n->body)->prev_font); switch (n->type) { case ROFFT_TEXT: break; case ROFFT_TBL: break; case ROFFT_EQN: break; default: if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) break; (void)(*termacts[n->tok].post)(p, &npair, meta, n); /* * Explicit end tokens not only call the post * handler, but also tell the respective block * that it must not call the post handler again. */ if (ENDBODY_NOT != n->end) n->body->flags |= MDOC_ENDED; /* * End of line terminating an implicit block * while an explicit block is still open. * Continue the explicit block without spacing. */ if (ENDBODY_NOSPACE == n->end) p->flags |= TERMP_NOSPACE; break; } if (MDOC_EOS & n->flags) p->flags |= TERMP_SENTENCE; if (MDOC_ll != n->tok) { p->offset = offset; p->rmargin = rmargin; } }
static void print_man_node(DECL_ARGS) { size_t rm, rmax; int c; switch (n->type) { case ROFFT_TEXT: /* * If we have a blank line, output a vertical space. * If we have a space as the first character, break * before printing the line's data. */ if ('\0' == *n->string) { term_vspace(p); return; } else if (' ' == *n->string && MAN_LINE & n->flags) term_newln(p); term_word(p, n->string); goto out; case ROFFT_EQN: if ( ! (n->flags & MAN_LINE)) p->flags |= TERMP_NOSPACE; term_eqn(p, n->eqn); if (n->next != NULL && ! (n->next->flags & MAN_LINE)) p->flags |= TERMP_NOSPACE; return; case ROFFT_TBL: if (p->tbl.cols == NULL) term_vspace(p); term_tbl(p, n->span); return; default: break; } if ( ! (MAN_NOTEXT & termacts[n->tok].flags)) term_fontrepl(p, TERMFONT_NONE); c = 1; if (termacts[n->tok].pre) c = (*termacts[n->tok].pre)(p, mt, n, meta); if (c && n->child) print_man_nodelist(p, mt, n->child, meta); if (termacts[n->tok].post) (*termacts[n->tok].post)(p, mt, n, meta); if ( ! (MAN_NOTEXT & termacts[n->tok].flags)) term_fontrepl(p, TERMFONT_NONE); out: /* * If we're in a literal context, make sure that words * together on the same line stay together. This is a * POST-printing call, so we check the NEXT word. Since * -man doesn't have nested macros, we don't need to be * more specific than this. */ if (mt->fl & MANT_LITERAL && ! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) && (n->next == NULL || n->next->flags & MAN_LINE)) { rm = p->rmargin; rmax = p->maxrmargin; p->rmargin = p->maxrmargin = TERM_MAXMARGIN; p->flags |= TERMP_NOSPACE; if (n->string != NULL && *n->string != '\0') term_flushln(p); else term_newln(p); if (rm < rmax && n->parent->tok == MAN_HP) { p->offset = rm; p->rmargin = rmax; } else p->rmargin = rm; p->maxrmargin = rmax; } if (MAN_EOS & n->flags) p->flags |= TERMP_SENTENCE; }
static void print_man_node(DECL_ARGS) { size_t rm, rmax; int c; switch (n->type) { case(MAN_TEXT): /* * If we have a blank line, output a vertical space. * If we have a space as the first character, break * before printing the line's data. */ if ('\0' == *n->string) { term_vspace(p); return; } else if (' ' == *n->string && MAN_LINE & n->flags) term_newln(p); term_word(p, n->string); /* * If we're in a literal context, make sure that words * togehter on the same line stay together. This is a * POST-printing call, so we check the NEXT word. Since * -man doesn't have nested macros, we don't need to be * more specific than this. */ if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) && (NULL == n->next || n->next->line > n->line)) { rm = p->rmargin; rmax = p->maxrmargin; p->rmargin = p->maxrmargin = TERM_MAXMARGIN; p->flags |= TERMP_NOSPACE; term_flushln(p); p->rmargin = rm; p->maxrmargin = rmax; } if (MAN_EOS & n->flags) p->flags |= TERMP_SENTENCE; return; case (MAN_EQN): term_eqn(p, n->eqn); return; case (MAN_TBL): /* * Tables are preceded by a newline. Then process a * table line, which will cause line termination, */ if (TBL_SPAN_FIRST & n->span->flags) term_newln(p); term_tbl(p, n->span); return; default: break; } if ( ! (MAN_NOTEXT & termacts[n->tok].flags)) term_fontrepl(p, TERMFONT_NONE); c = 1; if (termacts[n->tok].pre) c = (*termacts[n->tok].pre)(p, mt, n, m); if (c && n->child) print_man_nodelist(p, mt, n->child, m); if (termacts[n->tok].post) (*termacts[n->tok].post)(p, mt, n, m); if ( ! (MAN_NOTEXT & termacts[n->tok].flags)) term_fontrepl(p, TERMFONT_NONE); if (MAN_EOS & n->flags) p->flags |= TERMP_SENTENCE; }
/* ARGSUSED */ static void print_mdoc_node(DECL_ARGS) { int chld; const void *font; struct termpair npair; size_t offset, rmargin; chld = 1; offset = p->offset; rmargin = p->rmargin; font = term_fontq(p); memset(&npair, 0, sizeof(struct termpair)); npair.ppair = pair; /* * Keeps only work until the end of a line. If a keep was * invoked in a prior line, revert it to PREKEEP. * * Also let SYNPRETTY sections behave as if they were wrapped * in a `Bk' block. */ if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) { if (n->prev && n->prev->line != n->line) { p->flags &= ~TERMP_KEEP; p->flags |= TERMP_PREKEEP; } else if (NULL == n->prev) { if (n->parent && n->parent->line != n->line) { p->flags &= ~TERMP_KEEP; p->flags |= TERMP_PREKEEP; } } } /* * Since SYNPRETTY sections aren't "turned off" with `Ek', * we have to intuit whether we should disable formatting. */ if ( ! (MDOC_SYNPRETTY & n->flags) && ((n->prev && MDOC_SYNPRETTY & n->prev->flags) || (n->parent && MDOC_SYNPRETTY & n->parent->flags))) p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); /* * After the keep flags have been set up, we may now * produce output. Note that some pre-handlers do so. */ switch (n->type) { case (MDOC_TEXT): if (' ' == *n->string && MDOC_LINE & n->flags) term_newln(p); if (MDOC_DELIMC & n->flags) p->flags |= TERMP_NOSPACE; term_word(p, n->string); if (MDOC_DELIMO & n->flags) p->flags |= TERMP_NOSPACE; break; case (MDOC_EQN): term_eqn(p, n->eqn); break; case (MDOC_TBL): term_tbl(p, n->span); break; default: if (termacts[n->tok].pre && ENDBODY_NOT == n->end) chld = (*termacts[n->tok].pre) (p, &npair, m, n); break; } if (chld && n->child) print_mdoc_nodelist(p, &npair, m, n->child); term_fontpopq(p, font); switch (n->type) { case (MDOC_TEXT): break; case (MDOC_TBL): break; case (MDOC_EQN): break; default: if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) break; (void)(*termacts[n->tok].post)(p, &npair, m, n); /* * Explicit end tokens not only call the post * handler, but also tell the respective block * that it must not call the post handler again. */ if (ENDBODY_NOT != n->end) n->pending->flags |= MDOC_ENDED; /* * End of line terminating an implicit block * while an explicit block is still open. * Continue the explicit block without spacing. */ if (ENDBODY_NOSPACE == n->end) p->flags |= TERMP_NOSPACE; break; } if (MDOC_EOS & n->flags) p->flags |= TERMP_SENTENCE; p->offset = offset; p->rmargin = rmargin; }