-/* $Id: mdoc_term.c,v 1.189 2010/09/26 10:00:42 kristaps Exp $ */
+/* $Id: mdoc_term.c,v 1.201 2010/12/22 11:15:16 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
static void termp_nm_post(DECL_ARGS);
static void termp_pf_post(DECL_ARGS);
static void termp_quote_post(DECL_ARGS);
-static void termp_quote_post(DECL_ARGS);
static void termp_sh_post(DECL_ARGS);
static void termp_ss_post(DECL_ARGS);
static int termp_fn_pre(DECL_ARGS);
static int termp_fo_pre(DECL_ARGS);
static int termp_ft_pre(DECL_ARGS);
+static int termp_igndelim_pre(DECL_ARGS);
static int termp_in_pre(DECL_ARGS);
static int termp_it_pre(DECL_ARGS);
static int termp_li_pre(DECL_ARGS);
static int termp_nd_pre(DECL_ARGS);
static int termp_nm_pre(DECL_ARGS);
static int termp_ns_pre(DECL_ARGS);
-static int termp_pf_pre(DECL_ARGS);
static int termp_quote_pre(DECL_ARGS);
static int termp_rs_pre(DECL_ARGS);
static int termp_rv_pre(DECL_ARGS);
{ NULL, NULL }, /* Eo */
{ termp_xx_pre, NULL }, /* Fx */
{ termp_bold_pre, NULL }, /* Ms */
- { NULL, NULL }, /* No */
+ { termp_igndelim_pre, NULL }, /* No */
{ termp_ns_pre, NULL }, /* Ns */
{ termp_xx_pre, NULL }, /* Nx */
{ termp_xx_pre, NULL }, /* Ox */
{ NULL, NULL }, /* Pc */
- { termp_pf_pre, termp_pf_post }, /* Pf */
+ { termp_igndelim_pre, termp_pf_post }, /* Pf */
{ termp_quote_pre, termp_quote_post }, /* Po */
{ termp_quote_pre, termp_quote_post }, /* Pq */
{ NULL, NULL }, /* Qc */
/*
* 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) {
+ 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;
}
}
+ /*
+ * 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);
+
if (chld && n->child)
print_mdoc_nodelist(p, &npair, m, n->child);
term_newln(p);
- if (MDOC_Bd == bl->tok && bl->data.Bd->comp)
+ if (MDOC_Bd == bl->tok && bl->norm->d.Bd.comp)
return;
- if (MDOC_Bl == bl->tok && bl->data.Bl->comp)
+ if (MDOC_Bl == bl->tok && bl->norm->d.Bl.comp)
return;
/* Do not vspace directly after Ss/Sh. */
/* A `-column' does not assert vspace within the list. */
- if (MDOC_Bl == bl->tok && LIST_column == bl->data.Bl->type)
+ if (MDOC_Bl == bl->tok && LIST_column == bl->norm->d.Bl.type)
if (n->prev && MDOC_It == n->prev->tok)
return;
/* A `-diag' without body does not vspace. */
- if (MDOC_Bl == bl->tok && LIST_diag == bl->data.Bl->type)
+ if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->d.Bl.type)
if (n->prev && MDOC_It == n->prev->tok) {
assert(n->prev->body);
if (NULL == n->prev->body->child)
}
bl = n->parent->parent->parent;
- assert(bl->data.Bl);
- type = bl->data.Bl->type;
+ type = bl->norm->d.Bl.type;
/*
* First calculate width and offset. This is pretty easy unless
width = offset = 0;
- if (bl->data.Bl->offs)
- offset = a2offs(p, bl->data.Bl->offs);
+ if (bl->norm->d.Bl.offs)
+ offset = a2offs(p, bl->norm->d.Bl.offs);
switch (type) {
case (LIST_column):
* column.
* - For more than 5 columns, add only one column.
*/
- ncols = bl->data.Bl->ncols;
+ ncols = bl->norm->d.Bl.ncols;
/* LINTED */
dcol = ncols < 5 ? term_len(p, 4) :
nn->prev && i < (int)ncols;
nn = nn->prev, i++)
offset += dcol + a2width
- (p, bl->data.Bl->cols[i]);
+ (p, bl->norm->d.Bl.cols[i]);
/*
* When exceeding the declared number of columns, leave
* Use the declared column widths, extended as explained
* in the preceding paragraph.
*/
- width = a2width(p, bl->data.Bl->cols[i]) + dcol;
+ width = a2width(p, bl->norm->d.Bl.cols[i]) + dcol;
break;
default:
- if (NULL == bl->data.Bl->width)
+ if (NULL == bl->norm->d.Bl.width)
break;
/*
* number for buffering single arguments. See the above
* handling for column for how this changes.
*/
- assert(bl->data.Bl->width);
- width = a2width(p, bl->data.Bl->width) + term_len(p, 2);
+ assert(bl->norm->d.Bl.width);
+ width = a2width(p, bl->norm->d.Bl.width) + term_len(p, 2);
break;
}
if (MDOC_BLOCK == n->type)
return;
- type = n->parent->parent->parent->data.Bl->type;
+ type = n->parent->parent->parent->norm->d.Bl.type;
switch (type) {
case (LIST_item):
return;
}
- if (AUTH_split == n->data.An.auth) {
+ if (AUTH_split == n->norm->d.An.auth) {
p->flags &= ~TERMP_NOSPLIT;
p->flags |= TERMP_SPLIT;
- } else if (AUTH_nosplit == n->data.An.auth) {
+ } else if (AUTH_nosplit == n->norm->d.An.auth) {
p->flags &= ~TERMP_SPLIT;
p->flags |= TERMP_NOSPLIT;
}
} else if (MDOC_HEAD == n->type)
return(0);
- assert(n->data.Bd);
- if (n->data.Bd->offs)
- p->offset += a2offs(p, n->data.Bd->offs);
+ if (n->norm->d.Bd.offs)
+ p->offset += a2offs(p, n->norm->d.Bd.offs);
/*
* If -ragged or -filled are specified, the block does nothing
* lines are allowed.
*/
- if (DISP_literal != n->data.Bd->type &&
- DISP_unfilled != n->data.Bd->type)
+ if (DISP_literal != n->norm->d.Bd.type &&
+ DISP_unfilled != n->norm->d.Bd.type)
return(1);
tabwidth = p->tabwidth;
for (nn = n->child; nn; nn = nn->next) {
print_mdoc_node(p, pair, m, 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):
+ /* FALLTHROUGH */
+ case (MDOC_br):
+ /* FALLTHROUGH */
+ case (MDOC_sp):
+ /* FALLTHROUGH */
+ case (MDOC_Bl):
+ /* FALLTHROUGH */
+ case (MDOC_D1):
+ /* FALLTHROUGH */
+ case (MDOC_Dl):
+ /* FALLTHROUGH */
+ case (MDOC_Lp):
+ /* FALLTHROUGH */
+ case (MDOC_Pp):
+ continue;
+ default:
+ break;
+ }
if (nn->next && nn->next->line == nn->line)
continue;
term_flushln(p);
rm = p->rmargin;
rmax = p->maxrmargin;
- assert(n->data.Bd);
- if (DISP_literal == n->data.Bd->type ||
- DISP_unfilled == n->data.Bd->type)
+ if (DISP_literal == n->norm->d.Bd.type ||
+ DISP_unfilled == n->norm->d.Bd.type)
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
pp = NULL;
switch (n->tok) {
case (MDOC_Bsx):
- pp = "BSDI BSD/OS";
+ pp = "BSD/OS";
break;
case (MDOC_Dx):
pp = "DragonFly";
/* ARGSUSED */
static int
-termp_pf_pre(DECL_ARGS)
+termp_igndelim_pre(DECL_ARGS)
{
p->flags |= TERMP_IGNDELIM;
termp_pf_post(DECL_ARGS)
{
- p->flags &= ~TERMP_IGNDELIM;
p->flags |= TERMP_NOSPACE;
}
len = 0;
break;
default:
- assert(n->parent);
- if ((NULL == n->next || NULL == n->prev) &&
- (MDOC_Ss == n->parent->tok ||
- MDOC_Sh == n->parent->tok))
- return(0);
len = 1;
break;
}
else if (MDOC_BLOCK != n->type)
return(1);
- assert(n->data.Bf);
-
- if (FONT_Em == n->data.Bf->font)
+ if (FONT_Em == n->norm->d.Bf.font)
term_fontpush(p, TERMFONT_UNDER);
- else if (FONT_Sy == n->data.Bf->font)
+ else if (FONT_Sy == n->norm->d.Bf.font)
term_fontpush(p, TERMFONT_BOLD);
else
term_fontpush(p, TERMFONT_NONE);
nn = sv = n->child;
- if (NULL == nn->next)
+ if (NULL == nn || NULL == nn->next)
return(1);
for (nn = nn->next; nn; nn = nn->next)
case (MDOC_HEAD):
return(0);
case (MDOC_BODY):
- p->flags |= TERMP_PREKEEP;
+ if (n->parent->args || 0 == n->prev->nchild)
+ p->flags |= TERMP_PREKEEP;
break;
default:
abort();