-/* $Id: mdoc_term.c,v 1.167 2010/07/02 12:54:33 kristaps Exp $ */
+/* $Id: mdoc_term.c,v 1.179 2010/07/27 08:38:04 kristaps Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 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
#include "mandoc.h"
#include "out.h"
#include "term.h"
-#include "regs.h"
#include "mdoc.h"
#include "chars.h"
#include "main.h"
static size_t a2height(const struct termp *, const char *);
static size_t a2offs(const struct termp *, const char *);
-static int arg_hasattr(int, const struct mdoc_node *);
-static int arg_getattr(int, const struct mdoc_node *);
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
{ termp_bl_pre, termp_bl_post }, /* Bl */
{ NULL, NULL }, /* El */
{ termp_it_pre, termp_it_post }, /* It */
- { NULL, NULL }, /* Ad */
+ { termp_under_pre, NULL }, /* Ad */
{ termp_an_pre, termp_an_post }, /* An */
{ termp_under_pre, NULL }, /* Ar */
{ termp_cd_pre, NULL }, /* Cd */
{ termp_under_pre, NULL }, /* Em */
{ NULL, NULL }, /* Eo */
{ termp_xx_pre, NULL }, /* Fx */
- { termp_bold_pre, NULL }, /* Ms */ /* FIXME: convert to symbol? */
+ { termp_bold_pre, NULL }, /* Ms */
{ NULL, NULL }, /* No */
{ termp_ns_pre, NULL }, /* Ns */
{ termp_xx_pre, NULL }, /* Nx */
else if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
chld = (*termacts[n->tok].pre)(p, &npair, m, n);
+ /*
+ * Keeps only work until the end of a line. If a keep was
+ * invoked in a prior line, revert it to PREKEEP.
+ */
+
+ if (TERMP_KEEP & p->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;
+ }
+ }
+ }
+
if (chld && n->child)
print_mdoc_nodelist(p, &npair, m, n->child);
}
-/*
- * Return 1 if an argument has a particular argument value or 0 if it
- * does not. See arg_getattr().
- */
-static int
-arg_hasattr(int arg, const struct mdoc_node *n)
-{
-
- return(-1 != arg_getattr(arg, n));
-}
-
-
-/*
- * Get the index of an argument in a node's argument list or -1 if it
- * does not exist.
- */
-static int
-arg_getattr(int v, const struct mdoc_node *n)
-{
- int i;
-
- if (NULL == n->args)
- return(0);
-
- for (i = 0; i < (int)n->args->argc; i++)
- if (n->args->argv[i].arg == v)
- return(i);
-
- return(-1);
-}
-
-
/*
* Determine how much space to print out before block elements of `It'
* (and thus `Bl') and `Bd'. And then go ahead and print that space,
{
const struct mdoc_node *bl, *nn;
char buf[7];
- int i, col;
+ int i;
size_t width, offset, ncols, dcol;
enum mdoc_list type;
if (MDOC_HEAD == n->type)
break;
- col = arg_getattr(MDOC_Column, bl);
-
/*
* Imitate groff's column handling:
* - For each earlier column, add its width.
* column.
* - For more than 5 columns, add only one column.
*/
- ncols = bl->args->argv[col].sz;
+ ncols = bl->data.Bl->ncols;
+
/* LINTED */
dcol = ncols < 5 ? term_len(p, 4) :
ncols == 5 ? term_len(p, 3) : term_len(p, 1);
nn->prev && i < (int)ncols;
nn = nn->prev, i++)
offset += dcol + a2width
- (p, bl->args->argv[col].value[i]);
+ (p, bl->data.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->args->argv[col].value[i]) + dcol;
+ width = a2width(p, bl->data.Bl->cols[i]) + dcol;
break;
default:
if (NULL == bl->data.Bl->width)
if (NULL == n->child && NULL == m->name)
return(0);
- synopsis_pre(p, n);
+ if (MDOC_HEAD == n->type)
+ synopsis_pre(p, n->parent);
if (MDOC_HEAD == n->type && n->next->child) {
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK | TERMP_HANG;
return;
}
- if (arg_hasattr(MDOC_Split, n)) {
+ if (AUTH_split == n->data.An.auth) {
p->flags &= ~TERMP_NOSPLIT;
p->flags |= TERMP_SPLIT;
- } else {
+ } else if (AUTH_nosplit == n->data.An.auth) {
p->flags &= ~TERMP_SPLIT;
p->flags |= TERMP_NOSPLIT;
}
static int
termp_bd_pre(DECL_ARGS)
{
- size_t tabwidth;
- size_t rm, rmax;
+ size_t tabwidth, rm, rmax;
const struct mdoc_node *nn;
if (MDOC_BLOCK == n->type) {
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
for (nn = n->child; nn; nn = nn->next) {
- p->flags |= TERMP_NOSPACE;
+ if (nn->prev && nn->prev->line < nn->line)
+ term_newln(p);
print_mdoc_node(p, pair, m, nn);
- if (NULL == nn->prev ||
- nn->prev->line < nn->line ||
- NULL == nn->next)
- term_flushln(p);
}
p->tabwidth = tabwidth;
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;
}
return(1);
}
+ if (NULL == n->child)
+ return(0);
+
/* XXX: we drop non-initial arguments as per groff. */
- assert(n->child);
assert(n->child->string);
term_fontpush(p, TERMFONT_BOLD);
term_word(p, n->child->string);
{
assert(n->child && MDOC_TEXT == n->child->type);
- if (0 == strcmp("on", n->child->string))
+ if (0 == strcmp("on", n->child->string)) {
+ if (p->col)
+ p->flags &= ~TERMP_NOSPACE;
p->flags &= ~TERMP_NONOSPACE;
- else
+ } else
p->flags |= TERMP_NONOSPACE;
return(0);