-/* $Id: man_term.c,v 1.85 2010/09/15 14:36:16 kristaps Exp $ */
+/* $Id: man_term.c,v 1.95 2011/01/11 00:39:00 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
static void print_bvspace(struct termp *,
const struct man_node *);
+static int pre_alternate(DECL_ARGS);
static int pre_B(DECL_ARGS);
-static int pre_BI(DECL_ARGS);
static int pre_HP(DECL_ARGS);
static int pre_I(DECL_ARGS);
static int pre_IP(DECL_ARGS);
static int pre_PP(DECL_ARGS);
-static int pre_RB(DECL_ARGS);
-static int pre_RI(DECL_ARGS);
static int pre_RS(DECL_ARGS);
static int pre_SH(DECL_ARGS);
static int pre_SS(DECL_ARGS);
static int pre_in(DECL_ARGS);
static int pre_literal(DECL_ARGS);
static int pre_sp(DECL_ARGS);
+static int pre_ft(DECL_ARGS);
static void post_IP(DECL_ARGS);
static void post_HP(DECL_ARGS);
{ pre_HP, post_HP, 0 }, /* HP */
{ NULL, NULL, 0 }, /* SM */
{ pre_B, NULL, 0 }, /* SB */
- { pre_BI, NULL, 0 }, /* BI */
- { pre_BI, NULL, 0 }, /* IB */
- { pre_RB, NULL, 0 }, /* BR */
- { pre_RB, NULL, 0 }, /* RB */
+ { pre_alternate, NULL, 0 }, /* BI */
+ { pre_alternate, NULL, 0 }, /* IB */
+ { pre_alternate, NULL, 0 }, /* BR */
+ { pre_alternate, NULL, 0 }, /* RB */
{ NULL, NULL, 0 }, /* R */
{ pre_B, NULL, 0 }, /* B */
{ pre_I, NULL, 0 }, /* I */
- { pre_RI, NULL, 0 }, /* IR */
- { pre_RI, NULL, 0 }, /* RI */
+ { pre_alternate, NULL, 0 }, /* IR */
+ { pre_alternate, NULL, 0 }, /* RI */
{ NULL, NULL, MAN_NOTEXT }, /* na */
- { pre_I, NULL, 0 }, /* i */
{ pre_sp, NULL, MAN_NOTEXT }, /* sp */
{ pre_literal, NULL, 0 }, /* nf */
{ pre_literal, NULL, 0 }, /* fi */
- { NULL, NULL, 0 }, /* r */
{ NULL, NULL, 0 }, /* RE */
{ pre_RS, post_RS, 0 }, /* RS */
{ pre_ign, NULL, 0 }, /* DT */
{ pre_ign, NULL, 0 }, /* UC */
{ pre_ign, NULL, 0 }, /* PD */
- { pre_sp, NULL, MAN_NOTEXT }, /* Sp */
- { pre_literal, NULL, 0 }, /* Vb */
- { pre_literal, NULL, 0 }, /* Ve */
{ pre_ign, NULL, 0 }, /* AT */
{ pre_in, NULL, MAN_NOTEXT }, /* in */
+ { pre_ft, NULL, MAN_NOTEXT }, /* ft */
};
{
term_newln(p);
- switch (n->tok) {
- case (MAN_Vb):
- /* FALLTHROUGH */
- case (MAN_nf):
+
+ if (MAN_nf == n->tok)
mt->fl |= MANT_LITERAL;
- return(MAN_Vb != n->tok);
- default:
+ else
mt->fl &= ~MANT_LITERAL;
- break;
- }
return(1);
}
-
-
/* ARGSUSED */
static int
-pre_RB(DECL_ARGS)
+pre_alternate(DECL_ARGS)
{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_RB == n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else if ( ! (i % 2) && MAN_RB != n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else
- term_fontrepl(p, TERMFONT_NONE);
-
- if (i > 0)
- p->flags |= TERMP_NOSPACE;
+ enum termfont font[2];
+ const struct man_node *nn;
+ int savelit, i;
- print_man_node(p, mt, nn, m);
+ switch (n->tok) {
+ case (MAN_RB):
+ font[0] = TERMFONT_NONE;
+ font[1] = TERMFONT_BOLD;
+ break;
+ case (MAN_RI):
+ font[0] = TERMFONT_NONE;
+ font[1] = TERMFONT_UNDER;
+ break;
+ case (MAN_BR):
+ font[0] = TERMFONT_BOLD;
+ font[1] = TERMFONT_NONE;
+ break;
+ case (MAN_BI):
+ font[0] = TERMFONT_BOLD;
+ font[1] = TERMFONT_UNDER;
+ break;
+ case (MAN_IR):
+ font[0] = TERMFONT_UNDER;
+ font[1] = TERMFONT_NONE;
+ break;
+ case (MAN_IB):
+ font[0] = TERMFONT_UNDER;
+ font[1] = TERMFONT_BOLD;
+ break;
+ default:
+ abort();
}
- return(0);
-}
+ savelit = MANT_LITERAL & mt->fl;
+ mt->fl &= ~MANT_LITERAL;
-/* ARGSUSED */
-static int
-pre_RI(DECL_ARGS)
-{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_RI == n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else if ( ! (i % 2) && MAN_RI != n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else
- term_fontrepl(p, TERMFONT_NONE);
-
- if (i > 0)
- p->flags |= TERMP_NOSPACE;
-
+ for (i = 0, nn = n->child; nn; nn = nn->next, i = 1 - i) {
+ term_fontrepl(p, font[i]);
+ if (savelit && NULL == nn->next)
+ mt->fl |= MANT_LITERAL;
print_man_node(p, mt, nn, m);
+ if (nn->next)
+ p->flags |= TERMP_NOSPACE;
}
+
return(0);
}
-
/* ARGSUSED */
static int
-pre_BI(DECL_ARGS)
+pre_B(DECL_ARGS)
{
- const struct man_node *nn;
- int i;
-
- for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
- if (i % 2 && MAN_BI == n->tok)
- term_fontrepl(p, TERMFONT_UNDER);
- else if (i % 2)
- term_fontrepl(p, TERMFONT_BOLD);
- else if (MAN_BI == n->tok)
- term_fontrepl(p, TERMFONT_BOLD);
- else
- term_fontrepl(p, TERMFONT_UNDER);
-
- if (i)
- p->flags |= TERMP_NOSPACE;
- print_man_node(p, mt, nn, m);
- }
- return(0);
+ term_fontrepl(p, TERMFONT_BOLD);
+ return(1);
}
-
/* ARGSUSED */
static int
-pre_B(DECL_ARGS)
+pre_ft(DECL_ARGS)
{
+ const char *cp;
- term_fontrepl(p, TERMFONT_BOLD);
- return(1);
-}
+ 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);
+}
/* ARGSUSED */
static int
else
p->offset = v;
+ /* Don't let this creep beyond the right margin. */
+
+ if (p->offset > p->rmargin)
+ p->offset = p->rmargin;
+
return(0);
}
break;
}
- return(1);
+ return(MAN_HEAD != n->type);
}
{
const struct man_node *nn;
size_t len;
- int ival;
+ int savelit, ival;
switch (n->type) {
case (MAN_BODY):
len = mt->lmargin;
ival = -1;
- /* Calculate offset. */
-
+ /* Calculate the offset from the optional second argument. */
if (NULL != (nn = n->parent->head->child))
- if (NULL != (nn = nn->next)) {
- for ( ; nn->next; nn = nn->next)
- /* Do nothing. */ ;
+ if (NULL != (nn = nn->next))
if ((ival = a2width(p, nn->string)) >= 0)
len = (size_t)ival;
- }
switch (n->type) {
case (MAN_HEAD):
/* Set the saved left-margin. */
mt->lmargin = (size_t)ival;
- /* Don't print the length value. */
- for (nn = n->child; nn->next; nn = nn->next)
- print_man_node(p, mt, nn, m);
+ savelit = MANT_LITERAL & mt->fl;
+ mt->fl &= ~MANT_LITERAL;
+
+ if (n->child)
+ print_man_node(p, mt, n->child, m);
+
+ if (savelit)
+ mt->fl |= MANT_LITERAL;
+
return(0);
case (MAN_BODY):
p->offset = mt->offset + len;
p->rmargin = p->maxrmargin;
break;
case (MAN_BODY):
- term_flushln(p);
+ term_newln(p);
p->flags &= ~TERMP_NOLPAD;
break;
default:
{
const struct man_node *nn;
size_t len;
- int ival;
+ int savelit, ival;
switch (n->type) {
case (MAN_HEAD):
p->flags |= TERMP_NOBREAK;
- p->flags |= TERMP_TWOSPACE;
break;
case (MAN_BODY):
p->flags |= TERMP_NOLPAD;
p->offset = mt->offset;
p->rmargin = mt->offset + len;
+ savelit = MANT_LITERAL & mt->fl;
+ mt->fl &= ~MANT_LITERAL;
+
/* Don't print same-line elements. */
- for (nn = n->child; nn; nn = nn->next)
+ for (nn = n->child; nn; nn = nn->next)
if (nn->line > n->line)
print_man_node(p, mt, nn, m);
+ if (savelit)
+ mt->fl |= MANT_LITERAL;
+
if (ival >= 0)
mt->lmargin = (size_t)ival;
p->rmargin = p->maxrmargin;
break;
case (MAN_BODY):
- term_flushln(p);
+ term_newln(p);
p->flags &= ~TERMP_NOLPAD;
break;
default:
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
term_flushln(p);
+ p->flags &= ~TERMP_NOLPAD;
p->rmargin = rm;
p->maxrmargin = rmax;
}
break;
+ case (MAN_TBL):
+ if (TBL_SPAN_FIRST & n->span->flags)
+ term_newln(p);
+ term_tbl(p, n->span);
+ break;
default:
if ( ! (MAN_NOTEXT & termacts[n->tok].flags))
term_fontrepl(p, TERMFONT_NONE);
if (c && n->child)
print_man_nodelist(p, mt, n->child, m);
- if (MAN_TEXT != n->type) {
+ switch (n->type) {
+ case (MAN_TEXT):
+ /* FALLTHROUGH */
+ case (MAN_TBL):
+ break;
+ default:
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);
+ break;
}
if (MAN_EOS & n->flags)