-/* $Id: man_term.c,v 1.77 2010/06/25 18:53:14 kristaps Exp $ */
+/* $Id: man_term.c,v 1.93 2011/01/03 15:30:25 kristaps Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
* 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_TP(DECL_ARGS);
-static int pre_br(DECL_ARGS);
-static int pre_fi(DECL_ARGS);
static int pre_ign(DECL_ARGS);
-static int pre_nf(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);
static void post_TP(DECL_ARGS);
static const struct termact termacts[MAN_MAX] = {
- { pre_br, NULL, MAN_NOTEXT }, /* br */
+ { pre_sp, NULL, MAN_NOTEXT }, /* br */
{ NULL, NULL, 0 }, /* TH */
{ pre_SH, post_SH, 0 }, /* SH */
{ pre_SS, post_SS, 0 }, /* SS */
{ 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_nf, NULL, 0 }, /* nf */
- { pre_fi, NULL, 0 }, /* fi */
- { NULL, NULL, 0 }, /* r */
+ { pre_literal, NULL, 0 }, /* nf */
+ { pre_literal, NULL, 0 }, /* fi */
{ 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_nf, NULL, 0 }, /* Vb */
- { pre_fi, NULL, 0 }, /* Ve */
{ pre_ign, NULL, 0 }, /* AT */
+ { pre_in, NULL, MAN_NOTEXT }, /* in */
+ { pre_ft, NULL, MAN_NOTEXT }, /* ft */
};
/* ARGSUSED */
static int
-pre_fi(DECL_ARGS)
+pre_literal(DECL_ARGS)
{
- mt->fl &= ~MANT_LITERAL;
- return(1);
-}
-
+ term_newln(p);
-/* ARGSUSED */
-static int
-pre_nf(DECL_ARGS)
-{
+ if (MAN_nf == n->tok)
+ mt->fl |= MANT_LITERAL;
+ else
+ mt->fl &= ~MANT_LITERAL;
- mt->fl |= MANT_LITERAL;
- return(MAN_Vb != n->tok);
+ 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);
+ enum termfont font[2];
+ const struct man_node *nn;
+ int savelit, i;
- if (i > 0)
- p->flags |= TERMP_NOSPACE;
+ 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();
+ }
+
+ savelit = MANT_LITERAL & mt->fl;
+ mt->fl &= ~MANT_LITERAL;
+ 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_RI(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_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;
- print_man_node(p, mt, nn, m);
- }
- return(0);
+ term_fontrepl(p, TERMFONT_BOLD);
+ return(1);
}
-
/* ARGSUSED */
static int
-pre_BI(DECL_ARGS)
+pre_ft(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;
+ const char *cp;
- print_man_node(p, mt, nn, m);
+ 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
-pre_B(DECL_ARGS)
+pre_in(DECL_ARGS)
{
+ int len, less;
+ size_t v;
+ const char *cp;
- term_fontrepl(p, TERMFONT_BOLD);
- return(1);
+ term_newln(p);
+
+ if (NULL == n->child) {
+ p->offset = mt->offset;
+ return(0);
+ }
+
+ cp = n->child->string;
+ less = 0;
+
+ if ('-' == *cp)
+ less = -1;
+ else if ('+' == *cp)
+ less = 1;
+ else
+ cp--;
+
+ if ((len = a2width(p, ++cp)) < 0)
+ return(0);
+
+ v = (size_t)len;
+
+ if (less < 0)
+ p->offset -= p->offset > v ? v : p->offset;
+ else if (less > 0)
+ p->offset += v;
+ else
+ p->offset = v;
+
+ return(0);
}
{
size_t i, len;
- len = n->child ?
- a2height(p, n->child->string) : term_len(p, 1);
+ 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++)
+ for (i = 0; i < len; i++)
term_vspace(p);
return(0);
}
-/* ARGSUSED */
-static int
-pre_br(DECL_ARGS)
-{
-
- term_newln(p);
- return(0);
-}
-
-
/* ARGSUSED */
static int
pre_HP(DECL_ARGS)
break;
}
- return(1);
+ return(MAN_HEAD != n->type);
}
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)
p->rmargin = p->maxrmargin - term_strlen(p, buf);
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)