*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
int lmargin[MAXMARGINS]; /* margins (incl. vis. page) */
int lmargincur; /* index of current margin */
int lmarginsz; /* actual number of nested margins */
int lmargin[MAXMARGINS]; /* margins (incl. vis. page) */
int lmargincur; /* index of current margin */
int lmarginsz; /* actual number of nested margins */
static void print_man_foot(struct termp *,
const struct roff_meta *);
static void print_bvspace(struct termp *,
static void print_man_foot(struct termp *,
const struct roff_meta *);
static void print_bvspace(struct termp *,
static int pre_HP(DECL_ARGS);
static int pre_I(DECL_ARGS);
static int pre_IP(DECL_ARGS);
static int pre_HP(DECL_ARGS);
static int pre_I(DECL_ARGS);
static int pre_IP(DECL_ARGS);
static int pre_RS(DECL_ARGS);
static int pre_SH(DECL_ARGS);
static int pre_SS(DECL_ARGS);
static int pre_RS(DECL_ARGS);
static int pre_SH(DECL_ARGS);
static int pre_SS(DECL_ARGS);
static int pre_ign(DECL_ARGS);
static int pre_in(DECL_ARGS);
static int pre_literal(DECL_ARGS);
static int pre_ign(DECL_ARGS);
static int pre_in(DECL_ARGS);
static int pre_literal(DECL_ARGS);
static void post_IP(DECL_ARGS);
static void post_HP(DECL_ARGS);
static void post_RS(DECL_ARGS);
static void post_SH(DECL_ARGS);
static void post_IP(DECL_ARGS);
static void post_HP(DECL_ARGS);
static void post_RS(DECL_ARGS);
static void post_SH(DECL_ARGS);
-static const struct termact termacts[MAN_MAX] = {
- { pre_sp, NULL, MAN_NOTEXT }, /* br */
+static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
{ NULL, NULL, 0 }, /* TH */
{ pre_SH, post_SH, 0 }, /* SH */
{ NULL, NULL, 0 }, /* TH */
{ pre_SH, post_SH, 0 }, /* SH */
- { pre_SS, post_SS, 0 }, /* SS */
+ { pre_SS, post_SH, 0 }, /* SS */
{ pre_TP, post_TP, 0 }, /* TP */
{ pre_TP, post_TP, 0 }, /* TP */
- { pre_PP, NULL, 0 }, /* LP */
+ { pre_TP, post_TP, 0 }, /* TQ */
+ { pre_abort, NULL, 0 }, /* LP */
{ pre_PP, NULL, 0 }, /* PP */
{ pre_PP, NULL, 0 }, /* PP */
- { pre_PP, NULL, 0 }, /* P */
+ { pre_abort, NULL, 0 }, /* P */
{ pre_IP, post_IP, 0 }, /* IP */
{ pre_HP, post_HP, 0 }, /* HP */
{ NULL, NULL, 0 }, /* SM */
{ pre_IP, post_IP, 0 }, /* IP */
{ pre_HP, post_HP, 0 }, /* HP */
{ NULL, NULL, 0 }, /* SM */
{ pre_I, NULL, 0 }, /* I */
{ pre_alternate, NULL, 0 }, /* IR */
{ pre_alternate, NULL, 0 }, /* RI */
{ pre_I, NULL, 0 }, /* I */
{ pre_alternate, NULL, 0 }, /* IR */
{ pre_alternate, NULL, 0 }, /* RI */
- { pre_sp, NULL, MAN_NOTEXT }, /* sp */
- { pre_literal, NULL, 0 }, /* nf */
- { pre_literal, NULL, 0 }, /* fi */
{ NULL, NULL, 0 }, /* RE */
{ pre_RS, post_RS, 0 }, /* RS */
{ NULL, NULL, 0 }, /* RE */
{ pre_RS, post_RS, 0 }, /* RS */
- { pre_ign, NULL, 0 }, /* DT */
+ { pre_DT, NULL, 0 }, /* DT */
{ pre_ign, NULL, MAN_NOTEXT }, /* UC */
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
{ pre_ign, NULL, 0 }, /* AT */
{ pre_in, NULL, MAN_NOTEXT }, /* in */
{ pre_ign, NULL, MAN_NOTEXT }, /* UC */
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
{ pre_ign, NULL, 0 }, /* AT */
{ pre_in, NULL, MAN_NOTEXT }, /* in */
- { pre_ft, NULL, MAN_NOTEXT }, /* ft */
+ { pre_SY, post_SY, 0 }, /* SY */
+ { NULL, NULL, 0 }, /* YS */
{ pre_OP, NULL, 0 }, /* OP */
{ pre_literal, NULL, 0 }, /* EX */
{ pre_literal, NULL, 0 }, /* EE */
{ pre_UR, post_UR, 0 }, /* UR */
{ NULL, NULL, 0 }, /* UE */
{ pre_OP, NULL, 0 }, /* OP */
{ pre_literal, NULL, 0 }, /* EX */
{ pre_literal, NULL, 0 }, /* EE */
{ pre_UR, post_UR, 0 }, /* UR */
{ NULL, NULL, 0 }, /* UE */
- { pre_ll, NULL, MAN_NOTEXT }, /* ll */
+ { pre_UR, post_UR, 0 }, /* MT */
+ { NULL, NULL, 0 }, /* ME */
-
- p->overstep = 0;
- p->rmargin = p->maxrmargin = p->defrmargin;
- p->tabwidth = term_len(p, 5);
-
- n = man_node(man)->child;
- meta = man_meta(man);
-
- memset(&mt, 0, sizeof(struct mtermp));
-
+ save_defindent = p->defindent;
+ if (p->synopsisonly == 0 && p->defindent == 0)
+ p->defindent = 7;
+ p->tcol->rmargin = p->maxrmargin = p->defrmargin;
+ term_tab_set(p, NULL);
+ term_tab_set(p, "T");
+ term_tab_set(p, ".5i");
+
+ memset(&mt, 0, sizeof(mt));
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
mt.offset = term_len(p, p->defindent);
mt.pardist = 1;
mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);
mt.offset = term_len(p, p->defindent);
mt.pardist = 1;
- while (n != NULL) {
- if (n->tok == MAN_SH &&
- n->child->child->type == ROFFT_TEXT &&
- !strcmp(n->child->child->string, "SYNOPSIS")) {
- if (n->child->next->child != NULL)
- print_man_nodelist(p, &mt,
- n->child->next->child, meta);
- term_newln(p);
+ for (nn = NULL; n != NULL; n = n->next) {
+ if (n->tok != MAN_SH)
+ continue;
+ nc = n->child->child;
+ if (nc->type != ROFFT_TEXT)
+ continue;
+ if (strcmp(nc->string, "SYNOPSIS") == 0)
+ if (n == NULL)
+ n = nn;
+ p->flags |= TERMP_NOSPACE;
+ if (n != NULL && (n = n->child->next->child) != NULL)
+ print_man_nodelist(p, &mt, n, man);
+ term_newln(p);
- if (p->defindent == 0)
- p->defindent = 7;
- term_begin(p, print_man_head, print_man_foot, meta);
+ term_begin(p, print_man_head, print_man_foot, man);
- print_man_nodelist(p, &mt, n, meta);
+ print_man_nodelist(p, &mt, n, man);
/*
* 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.
*/
/*
* 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;
+ if (n->parent->tok == MAN_HP && p->tcol->rmargin < p->maxrmargin) {
+ p->tcol->offset = p->tcol->rmargin;
+ p->tcol->rmargin = p->maxrmargin;
-
- savelit = MANT_LITERAL & mt->fl;
- mt->fl &= ~MANT_LITERAL;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i = 1 - i) {
+ for (i = 0, nn = n->child; nn != NULL; nn = nn->next, i = 1 - i) {
- if (savelit && NULL == nn->next)
- mt->fl |= MANT_LITERAL;
- print_man_node(p, mt, nn, meta);
- if (nn->next)
+ assert(nn->type == ROFFT_TEXT);
+ term_word(p, nn->string);
+ if (nn->flags & NODE_EOS)
+ p->flags |= TERMP_SENTENCE;
+ if (nn->next != NULL)
term_fontrepl(p, TERMFONT_UNDER);
term_word(p, n->next->string);
}
term_fontrepl(p, TERMFONT_UNDER);
term_word(p, n->next->string);
}
- return(0);
-}
-
-static int
-pre_ft(DECL_ARGS)
-{
- const char *cp;
-
- if (NULL == n->child) {
- term_fontlast(p);
- return(0);
- }
-
- cp = n->child->string;
- switch (*cp) {
- case '4':
- /* FALLTHROUGH */
- case '3':
- /* FALLTHROUGH */
- case 'B':
- term_fontrepl(p, TERMFONT_BOLD);
- break;
- case '2':
- /* FALLTHROUGH */
- case 'I':
- term_fontrepl(p, TERMFONT_UNDER);
- break;
- case 'P':
- term_fontlast(p);
- break;
- case '1':
- /* FALLTHROUGH */
- case 'C':
- /* FALLTHROUGH */
- case 'R':
- term_fontrepl(p, TERMFONT_NONE);
- break;
- default:
- break;
- }
- return(0);
- p->offset = v;
- if (p->offset > SHRT_MAX)
- p->offset = term_len(p, p->defindent);
+ p->tcol->offset = v;
+ if (p->tcol->offset > SHRT_MAX)
+ p->tcol->offset = term_len(p, p->defindent);
- 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);
+ term_tab_set(p, NULL);
+ term_tab_set(p, "T");
+ term_tab_set(p, ".5i");
+ return 0;
- a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su) / 24;
+ a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
+ len = term_hen(p, &su);
switch (n->type) {
case ROFFT_BLOCK:
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
print_bvspace(p, n, mt->pardist);
break;
switch (n->type) {
case ROFFT_BLOCK:
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
print_bvspace(p, n, mt->pardist);
break;
}
/* Calculate the offset from the optional second argument. */
if ((nn = n->parent->head->child) != NULL &&
(nn = nn->next) != NULL &&
}
/* Calculate the offset from the optional second argument. */
if ((nn = n->parent->head->child) != NULL &&
(nn = nn->next) != NULL &&
- a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su) / 24;
+ a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
+ len = term_hen(p, &su);
- p->offset = mt->offset;
- p->rmargin = mt->offset + len;
-
- savelit = MANT_LITERAL & mt->fl;
- mt->fl &= ~MANT_LITERAL;
-
- if (n->child)
+ p->tcol->offset = mt->offset;
+ p->tcol->rmargin = mt->offset + len;
+ if (n->child != NULL)
print_man_node(p, mt, n->child, meta);
print_man_node(p, mt, n->child, meta);
- nn->string != NULL && ! (MAN_LINE & nn->flags) &&
- a2roffsu(nn->string, &su, SCALE_EN)) {
- len = term_hspan(p, &su) / 24;
+ nn->string != NULL && ! (NODE_LINE & nn->flags) &&
+ a2roffsu(nn->string, &su, SCALE_EN) != NULL) {
+ len = term_hen(p, &su);
- p->offset = mt->offset;
- p->rmargin = mt->offset + len;
-
- savelit = MANT_LITERAL & mt->fl;
- mt->fl &= ~MANT_LITERAL;
+ p->tcol->offset = mt->offset;
+ p->tcol->rmargin = mt->offset + len;
print_man_node(p, mt, nn, meta);
nn = nn->next;
}
print_man_node(p, mt, nn, meta);
nn = nn->next;
}
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
- do {
- n = n->prev;
- } while (n != NULL && n->tok != MAN_MAX &&
- termacts[n->tok].flags & MAN_NOTEXT);
- if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
+ if ((n = roff_node_prev(n)) == NULL ||
+ (n->tok == MAN_SS && roff_node_child(n->body) == NULL))
- p->offset = term_len(p, 3);
- p->rmargin = mt->offset;
+ p->tcol->offset = term_len(p, 3);
+ p->tcol->rmargin = mt->offset;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
- do {
- n = n->prev;
- } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
- if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
+ if ((n = roff_node_prev(n)) == NULL ||
+ (n->tok == MAN_SH && roff_node_child(n->body) == NULL))
- else if (a2roffsu(n->child->string, &su, SCALE_EN))
- n->aux = term_hspan(p, &su) / 24;
+ else if (a2roffsu(n->child->string, &su, SCALE_EN) != NULL)
+ n->aux = term_hen(p, &su);
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
n->aux = -mt->offset;
else if (n->aux > SHRT_MAX)
n->aux = term_len(p, p->defindent);
mt->offset += n->aux;
if (n->aux < 0 && (size_t)(-n->aux) > mt->offset)
n->aux = -mt->offset;
else if (n->aux > SHRT_MAX)
n->aux = term_len(p, p->defindent);
mt->offset += n->aux;
+ const struct roff_node *nn;
+ int len;
+
+ switch (n->type) {
+ case ROFFT_BLOCK:
+ if ((nn = roff_node_prev(n)) == NULL || nn->tok != MAN_SY)
+ print_bvspace(p, n, mt->pardist);
+ return 1;
+ case ROFFT_HEAD:
+ case ROFFT_BODY:
+ break;
+ default:
+ abort();
+ }
+
+ nn = n->parent->head->child;
+ len = nn == NULL ? 1 : term_strlen(p, nn->string) + 1;
- return (n->type != ROFFT_HEAD);
+ switch (n->type) {
+ case ROFFT_HEAD:
+ p->tcol->offset = mt->offset;
+ p->tcol->rmargin = mt->offset + len;
+ if (n->next->child == NULL ||
+ (n->next->child->flags & NODE_NOFILL) == 0)
+ p->flags |= TERMP_NOBREAK;
+ term_fontrepl(p, TERMFONT_BOLD);
+ break;
+ case ROFFT_BODY:
+ mt->lmargin[mt->lmargincur] = len;
+ p->tcol->offset = mt->offset + len;
+ p->tcol->rmargin = p->maxrmargin;
+ p->flags |= TERMP_NOSPACE;
+ break;
+ default:
+ abort();
+ }
+ return 1;
print_man_node(p, mt, n->child->child, meta);
p->flags |= TERMP_NOSPACE;
print_man_node(p, mt, n->child->child, meta);
p->flags |= TERMP_NOSPACE;
* If we have a space as the first character, break
* before printing the line's data.
*/
* If we have a space as the first character, break
* before printing the line's data.
*/
- if (termacts[n->tok].pre)
- c = (*termacts[n->tok].pre)(p, mt, n, meta);
+ if (act->pre != NULL)
+ c = (*act->pre)(p, mt, n, meta);
print_man_nodelist(p, mt, n->child, meta);
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))
+ if (act->post != NULL)
+ (*act->post)(p, mt, n, meta);
+ if ((act->flags & MAN_NOTEXT) == 0 && n->tok != MAN_SM)
* -man doesn't have nested macros, we don't need to be
* more specific than this.
*/
* -man doesn't have nested macros, we don't need to be
* more specific than this.
*/
- (n->next == NULL || n->next->flags & MAN_LINE)) {
- rm = p->rmargin;
- rmax = p->maxrmargin;
- p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
- p->flags |= TERMP_NOSPACE;
+ (n->next == NULL || n->next->flags & NODE_LINE)) {
+ p->flags |= TERMP_BRNEVER | TERMP_NOSPACE;
- if (rm < rmax && n->parent->tok == MAN_HP) {
- p->offset = rm;
- p->rmargin = rmax;
- } else
- p->rmargin = rm;
- p->maxrmargin = rmax;
+ p->flags &= ~TERMP_BRNEVER;
+ if (p->tcol->rmargin < p->maxrmargin &&
+ n->parent->tok == MAN_HP) {
+ p->tcol->offset = p->tcol->rmargin;
+ p->tcol->rmargin = p->maxrmargin;
+ }
while (n != NULL) {
print_man_node(p, mt, n, meta);
n = n->next;
while (n != NULL) {
print_man_node(p, mt, n, meta);
n = n->next;
mandoc_asprintf(&title, "%s(%s)",
meta->title, meta->msec);
mandoc_asprintf(&title, "%s(%s)",
meta->title, meta->msec);
p->flags |= TERMP_NOSPACE;
term_word(p, meta->date);
p->flags |= TERMP_NOSPACE;
term_word(p, meta->date);
+
+ /*
+ * Reset the terminal state for more output after the footer:
+ * Some output modes, in particular PostScript and PDF, print
+ * the header and the footer into a buffer such that it can be
+ * reused for multiple output pages, then go on to format the
+ * main text.
+ */
+
+ p->tcol->offset = 0;
+ p->flags = 0;
+
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
(p->maxrmargin - vollen + term_len(p, 1)) / 2 :
vollen < p->maxrmargin ? p->maxrmargin - vollen : 0;
- p->offset = p->rmargin;
- p->rmargin = p->offset + vollen + titlen < p->maxrmargin ?
- p->maxrmargin - titlen : p->maxrmargin;
+ p->tcol->offset = p->tcol->rmargin;
+ p->tcol->rmargin = p->tcol->offset + vollen + titlen <
+ p->maxrmargin ? p->maxrmargin - titlen : p->maxrmargin;