-/* $Id: mdoc_term.c,v 1.26 2009/07/12 16:52:41 kristaps Exp $ */
+/* $Id: mdoc_term.c,v 1.38 2009/07/13 07:23:07 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
TERMP_BOLD /* TTYPE_LIST */
};
-/* XXX - clean this up. */
-
struct termpair {
struct termpair *ppair;
- int type;
-#define TERMPAIR_FLAG (1 << 0)
- int flag; /* Whether being used. */
- size_t offset; /* Left margin. */
- size_t rmargin; /* Right margin. */
- int count; /* Enum count. */
+ int flag;
+ int count;
};
-#define TERMPAIR_SETFLAG(termp, p, fl) \
- do { \
- assert(! (TERMPAIR_FLAG & (p)->type)); \
- (termp)->flags |= (fl); \
- (p)->flag = (fl); \
- (p)->type |= TERMPAIR_FLAG; \
- } while ( /* CONSTCOND */ 0)
-
-#define DECL_ARGS \
- struct termp *p, struct termpair *pair, \
- const struct mdoc_meta *meta, \
- const struct mdoc_node *node
-
-#define DECL_PRE(name) \
-static int name##_pre(DECL_ARGS)
-#define DECL_POST(name) \
-static void name##_post(DECL_ARGS)
-#define DECL_PREPOST(name) \
-DECL_PRE(name); \
-DECL_POST(name);
-
-DECL_PREPOST(termp__t);
-DECL_PREPOST(termp_aq);
-DECL_PREPOST(termp_bd);
-DECL_PREPOST(termp_bq);
-DECL_PREPOST(termp_brq);
-DECL_PREPOST(termp_d1);
-DECL_PREPOST(termp_dq);
-DECL_PREPOST(termp_fd);
-DECL_PREPOST(termp_fn);
-DECL_PREPOST(termp_fo);
-DECL_PREPOST(termp_ft);
-DECL_PREPOST(termp_in);
-DECL_PREPOST(termp_it);
-DECL_PREPOST(termp_lb);
-DECL_PREPOST(termp_op);
-DECL_PREPOST(termp_pf);
-DECL_PREPOST(termp_pq);
-DECL_PREPOST(termp_qq);
-DECL_PREPOST(termp_sh);
-DECL_PREPOST(termp_ss);
-DECL_PREPOST(termp_sq);
-DECL_PREPOST(termp_vt);
-
-DECL_PRE(termp__j);
-DECL_PRE(termp_ap);
-DECL_PRE(termp_ar);
-DECL_PRE(termp_at);
-DECL_PRE(termp_bf);
-DECL_PRE(termp_bt);
-DECL_PRE(termp_cd);
-DECL_PRE(termp_cm);
-DECL_PRE(termp_em);
-DECL_PRE(termp_ex);
-DECL_PRE(termp_fa);
-DECL_PRE(termp_fl);
-DECL_PRE(termp_ic);
-DECL_PRE(termp_lk);
-DECL_PRE(termp_ms);
-DECL_PRE(termp_mt);
-DECL_PRE(termp_nd);
-DECL_PRE(termp_nm);
-DECL_PRE(termp_ns);
-DECL_PRE(termp_xx);
-DECL_PRE(termp_pa);
-DECL_PRE(termp_pp);
-DECL_PRE(termp_rs);
-DECL_PRE(termp_rv);
-DECL_PRE(termp_sm);
-DECL_PRE(termp_st);
-DECL_PRE(termp_sx);
-DECL_PRE(termp_sy);
-DECL_PRE(termp_ud);
-DECL_PRE(termp_va);
-DECL_PRE(termp_xr);
-
-DECL_POST(termp___);
-DECL_POST(termp_bl);
-DECL_POST(termp_bx);
+#define DECL_ARGS struct termp *p, \
+ struct termpair *pair, \
+ const struct mdoc_meta *meta, \
+ const struct mdoc_node *node
struct termact {
int (*pre)(DECL_ARGS);
void (*post)(DECL_ARGS);
};
+static void termp____post(DECL_ARGS);
+static void termp__t_post(DECL_ARGS);
+static void termp_aq_post(DECL_ARGS);
+static void termp_bd_post(DECL_ARGS);
+static void termp_bl_post(DECL_ARGS);
+static void termp_bq_post(DECL_ARGS);
+static void termp_brq_post(DECL_ARGS);
+static void termp_bx_post(DECL_ARGS);
+static void termp_d1_post(DECL_ARGS);
+static void termp_dq_post(DECL_ARGS);
+static void termp_fd_post(DECL_ARGS);
+static void termp_fn_post(DECL_ARGS);
+static void termp_fo_post(DECL_ARGS);
+static void termp_ft_post(DECL_ARGS);
+static void termp_in_post(DECL_ARGS);
+static void termp_it_post(DECL_ARGS);
+static void termp_lb_post(DECL_ARGS);
+static void termp_op_post(DECL_ARGS);
+static void termp_pf_post(DECL_ARGS);
+static void termp_pq_post(DECL_ARGS);
+static void termp_qq_post(DECL_ARGS);
+static void termp_sh_post(DECL_ARGS);
+static void termp_sq_post(DECL_ARGS);
+static void termp_ss_post(DECL_ARGS);
+static void termp_vt_post(DECL_ARGS);
+
+static int termp__j_pre(DECL_ARGS);
+static int termp__t_pre(DECL_ARGS);
+static int termp_ap_pre(DECL_ARGS);
+static int termp_aq_pre(DECL_ARGS);
+static int termp_ar_pre(DECL_ARGS);
+static int termp_bd_pre(DECL_ARGS);
+static int termp_bf_pre(DECL_ARGS);
+static int termp_bq_pre(DECL_ARGS);
+static int termp_brq_pre(DECL_ARGS);
+static int termp_bt_pre(DECL_ARGS);
+static int termp_cd_pre(DECL_ARGS);
+static int termp_cm_pre(DECL_ARGS);
+static int termp_d1_pre(DECL_ARGS);
+static int termp_dq_pre(DECL_ARGS);
+static int termp_em_pre(DECL_ARGS);
+static int termp_ex_pre(DECL_ARGS);
+static int termp_fa_pre(DECL_ARGS);
+static int termp_fd_pre(DECL_ARGS);
+static int termp_fl_pre(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_ic_pre(DECL_ARGS);
+static int termp_in_pre(DECL_ARGS);
+static int termp_it_pre(DECL_ARGS);
+static int termp_lk_pre(DECL_ARGS);
+static int termp_ms_pre(DECL_ARGS);
+static int termp_mt_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_op_pre(DECL_ARGS);
+static int termp_pa_pre(DECL_ARGS);
+static int termp_pf_pre(DECL_ARGS);
+static int termp_pp_pre(DECL_ARGS);
+static int termp_pq_pre(DECL_ARGS);
+static int termp_qq_pre(DECL_ARGS);
+static int termp_rs_pre(DECL_ARGS);
+static int termp_rv_pre(DECL_ARGS);
+static int termp_sh_pre(DECL_ARGS);
+static int termp_sm_pre(DECL_ARGS);
+static int termp_sq_pre(DECL_ARGS);
+static int termp_ss_pre(DECL_ARGS);
+static int termp_sx_pre(DECL_ARGS);
+static int termp_sy_pre(DECL_ARGS);
+static int termp_ud_pre(DECL_ARGS);
+static int termp_va_pre(DECL_ARGS);
+static int termp_vt_pre(DECL_ARGS);
+static int termp_xr_pre(DECL_ARGS);
+static int termp_xx_pre(DECL_ARGS);
+
static const struct termact termacts[MDOC_MAX] = {
{ termp_ap_pre, NULL }, /* Ap */
{ NULL, NULL }, /* Dd */
{ NULL, NULL }, /* Ot */
{ termp_pa_pre, NULL }, /* Pa */
{ termp_rv_pre, NULL }, /* Rv */
- { termp_st_pre, NULL }, /* St */
+ { NULL, NULL }, /* St */
{ termp_va_pre, NULL }, /* Va */
{ termp_vt_pre, termp_vt_post }, /* Vt */
{ termp_xr_pre, NULL }, /* Xr */
{ NULL, NULL }, /* Ac */
{ termp_aq_pre, termp_aq_post }, /* Ao */
{ termp_aq_pre, termp_aq_post }, /* Aq */
- { termp_at_pre, NULL }, /* At */
+ { NULL, NULL }, /* At */
{ NULL, NULL }, /* Bc */
{ termp_bf_pre, NULL }, /* Bf */
{ termp_bq_pre, termp_bq_post }, /* Bo */
{ NULL, NULL }, /* Hf */
{ NULL, NULL }, /* Fr */
{ termp_ud_pre, NULL }, /* Ud */
- { termp_lb_pre, termp_lb_post }, /* Lb */
+ { NULL, termp_lb_post }, /* Lb */
{ termp_pp_pre, NULL }, /* Lp */
{ termp_lk_pre, NULL }, /* Lk */
{ termp_mt_pre, NULL }, /* Mt */
* Main output function. When this is called, assume that the
* tree is properly formed.
*/
-
print_head(p, mdoc_meta(m));
assert(mdoc_node(m));
assert(MDOC_ROOT == mdoc_node(m)->type);
{
int dochild;
struct termpair npair;
-
- /* Pre-processing. */
+ size_t offset, rmargin;
dochild = 1;
+ offset = p->offset;
+ rmargin = p->rmargin;
+
npair.ppair = pair;
- npair.type = 0;
- npair.offset = npair.rmargin = 0;
npair.flag = 0;
npair.count = 0;
/* Children. */
- if (TERMPAIR_FLAG & npair.type)
- p->flags |= npair.flag;
+ p->flags |= npair.flag;
if (dochild && node->child)
print_body(p, &npair, meta, node->child);
- if (TERMPAIR_FLAG & npair.type)
- p->flags &= ~npair.flag;
-
/* Post-processing. */
if (MDOC_TEXT != node->type)
if (termacts[node->tok].post)
(*termacts[node->tok].post)(p, &npair, meta, node);
+
+ p->offset = offset;
+ p->rmargin = rmargin;
+ p->flags &= ~npair.flag;
}
/* FALLTHROUGH */
case (MDOC_Column):
/* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
case (MDOC_Ohang):
return(n->args->argv[i].arg);
default:
break;
}
- /* FIXME: mandated by parser. */
-
- errx(1, "list type not supported");
- /* NOTREACHED */
+ return(-1);
}
/* Save parent attributes. */
- pair->offset = p->offset;
- pair->rmargin = p->rmargin;
pair->flag = p->flags;
/* Get list width and offset. */
(void)arg_getattrs(keys, vals, 3, bl);
type = arg_listtype(bl);
+ assert(-1 != type);
/* Calculate real width and offset. */
/*
* List-type can override the width in the case of fixed-head
* values (bullet, dash/hyphen, enum). Tags need a non-zero
- * offset.
+ * offset. FIXME: double-check that correct.
*/
switch (type) {
if (width < 5)
width = 5;
break;
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
case (MDOC_Tag):
if (0 == width)
width = 10;
case (MDOC_Diag):
term_word(p, "\\ ");
/* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
case (MDOC_Inset):
if (MDOC_BODY == node->type)
p->flags &= ~TERMP_NOSPACE;
/* FALLTHROUGH */
case (MDOC_Hyphen):
/* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
case (MDOC_Tag):
if (MDOC_HEAD == node->type)
p->flags |= TERMP_NOBREAK;
else
p->flags |= TERMP_NOLPAD;
+
+ if (MDOC_HEAD == node->type && MDOC_Hang == type)
+ p->flags |= TERMP_NONOBREAK;
+
if (MDOC_HEAD == node->type && MDOC_Tag == type)
if (NULL == node->next ||
NULL == node->next->child)
/* FALLTHROUGH */
case (MDOC_Hyphen):
/* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
case (MDOC_Tag):
if (MDOC_HEAD == node->type)
p->rmargin = p->offset + width;
/* FALLTHROUGH */
case (MDOC_Hyphen):
p->flags |= TERMP_BOLD;
- term_word(p, "\\-");
+ term_word(p, "\\(hy");
break;
case (MDOC_Enum):
(pair->ppair->ppair->count)++;
return;
type = arg_listtype(node->parent->parent->parent);
+ assert(-1 != type);
switch (type) {
case (MDOC_Diag):
break;
}
- p->offset = pair->offset;
- p->rmargin = pair->rmargin;
p->flags = pair->flag;
}
if (SEC_SYNOPSIS == node->sec)
term_newln(p);
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_PROG]);
+ pair->flag |= ttypes[TTYPE_PROG];
+ p->flags |= ttypes[TTYPE_PROG];
+
if (NULL == node->child)
term_word(p, meta->name);
termp_fl_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
+ pair->flag |= ttypes[TTYPE_CMD_FLAG];
+ p->flags |= ttypes[TTYPE_CMD_FLAG];
term_word(p, "\\-");
p->flags |= TERMP_NOSPACE;
return(1);
termp_ar_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_ARG]);
+ pair->flag |= ttypes[TTYPE_CMD_ARG];
return(1);
}
}
-/* ARGSUSED */
-static int
-termp_st_pre(DECL_ARGS)
-{
- const char *cp;
-
- if (node->child && (cp = mdoc_a2st(node->child->string)))
- term_word(p, cp);
- return(0);
-}
-
-
/* ARGSUSED */
static int
termp_rs_pre(DECL_ARGS)
{
int i;
- /* FIXME: mandated by parser. */
-
- if (-1 == (i = arg_getattr(MDOC_Std, node)))
- errx(1, "expected -std argument");
- if (1 != node->args->argv[i].sz)
- errx(1, "expected -std argument");
+ i = arg_getattr(MDOC_Std, node);
+ assert(-1 != i);
+ assert(node->args->argv[i].sz);
term_newln(p);
term_word(p, "The");
{
int i;
- /* FIXME: mandated by parser? */
-
- if (-1 == (i = arg_getattr(MDOC_Std, node)))
- errx(1, "expected -std argument");
- if (1 != node->args->argv[i].sz)
- errx(1, "expected -std argument");
+ i = arg_getattr(MDOC_Std, node);
+ assert(-1 != i);
+ assert(node->args->argv[i].sz);
term_word(p, "The");
p->flags |= ttypes[TTYPE_PROG];
if (MDOC_BODY != node->type)
return(1);
+
/*
* XXX: signed off by jmc@openbsd.org. This technically
* produces a minus sign after the Nd, which is wrong, but is
* consistent with the historic OpenBSD tmac file.
*/
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__linux__)
term_word(p, "\\-");
#else
term_word(p, "\\(em");
{
/* FIXME: this can be "type name". */
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
+ pair->flag |= ttypes[TTYPE_VAR_DECL];
return(1);
}
termp_vt_post(DECL_ARGS)
{
- if (node->sec == SEC_SYNOPSIS)
+ if (node->sec != SEC_SYNOPSIS)
+ return;
+ if (node->next && MDOC_Vt == node->next->tok)
+ term_newln(p);
+ else if (node->next)
term_vspace(p);
}
termp_fd_pre(DECL_ARGS)
{
- /*
- * FIXME: this naming is bad. This value is used, in general,
- * for the #include header or other preprocessor statement.
- */
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_DECL]);
+ pair->flag |= ttypes[TTYPE_FUNC_DECL];
return(1);
}
if (node->sec != SEC_SYNOPSIS)
return;
+
term_newln(p);
if (node->next && MDOC_Fd != node->next->tok)
term_vspace(p);
switch (node->type) {
case (MDOC_HEAD):
term_vspace(p);
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SECTION]);
+ pair->flag |= ttypes[TTYPE_SECTION];
break;
case (MDOC_BODY):
p->offset = INDENT;
}
-/* ARGSUSED */
-static int
-termp_lb_pre(DECL_ARGS)
-{
- const char *lb;
-
- assert(node->child && MDOC_TEXT == node->child->type);
- lb = mdoc_a2lib(node->child->string);
- if (lb) {
- term_word(p, lb);
- return(0);
- }
- term_word(p, "library");
- return(1);
-}
-
-
/* ARGSUSED */
static void
termp_lb_post(DECL_ARGS)
if (MDOC_BLOCK != node->type)
return(1);
term_newln(p);
- pair->offset = INDENT + 1;
- p->offset += pair->offset;
+ p->offset += (INDENT + 1);
return(1);
}
if (MDOC_BLOCK != node->type)
return;
term_newln(p);
- p->offset -= pair->offset;
}
if (SEC_SYNOPSIS == node->sec)
if (node->prev && MDOC_Fo == node->prev->tok)
term_vspace(p);
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_TYPE]);
+ pair->flag |= ttypes[TTYPE_FUNC_TYPE];
return(1);
}
termp_sx_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK]);
+ pair->flag |= ttypes[TTYPE_LINK];
return(1);
}
struct mdoc_node *n;
if (node->parent->tok != MDOC_Fo) {
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_ARG]);
+ pair->flag |= ttypes[TTYPE_FUNC_ARG];
return(1);
}
termp_va_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
+ pair->flag |= ttypes[TTYPE_VAR_DECL];
return(1);
}
if (NULL == node->parent->args)
errx(1, "missing display type");
- pair->offset = p->offset;
-
for (type = -1, i = 0;
i < (int)node->parent->args->argc; i++) {
switch (node->parent->args->argv[i].arg) {
term_flushln(p);
p->flags &= ~TERMP_LITERAL;
- p->offset = pair->offset;
p->flags |= TERMP_NOSPACE;
}
term_vspace(p);
break;
case (MDOC_HEAD):
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SSECTION]);
+ pair->flag |= ttypes[TTYPE_SSECTION];
p->offset = HALFINDENT;
break;
default:
termp_ss_post(DECL_ARGS)
{
- switch (node->type) {
- case (MDOC_HEAD):
+ if (MDOC_HEAD == node->type)
term_newln(p);
- p->offset = INDENT;
- break;
- default:
- break;
- }
}
termp_pa_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FILE]);
+ pair->flag |= ttypes[TTYPE_FILE];
return(1);
}
termp_em_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
+ pair->flag |= ttypes[TTYPE_EMPH];
return(1);
}
termp_cd_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CONFIG]);
+ pair->flag |= ttypes[TTYPE_CONFIG];
term_newln(p);
return(1);
}
termp_cm_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
+ pair->flag |= ttypes[TTYPE_CMD_FLAG];
return(1);
}
termp_ic_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD]);
+ pair->flag |= ttypes[TTYPE_CMD];
return(1);
}
termp_in_pre(DECL_ARGS)
{
- /* XXX This conforms to new-groff style. */
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_INCLUDE]);
+ pair->flag |= ttypes[TTYPE_INCLUDE];
+ p->flags |= ttypes[TTYPE_INCLUDE];
if (SEC_SYNOPSIS == node->sec)
term_word(p, "#include");
}
-/* ARGSUSED */
-static int
-termp_at_pre(DECL_ARGS)
-{
- const char *att;
-
- att = NULL;
-
- if (node->child)
- att = mdoc_a2att(node->child->string);
- if (NULL == att)
- att = "AT&T UNIX";
-
- term_word(p, att);
- return(0);
-}
-
-
/* ARGSUSED */
static int
termp_brq_pre(DECL_ARGS)
const struct mdoc_node *n;
if (MDOC_BODY == node->type) {
+ p->flags |= TERMP_NOSPACE;
term_word(p, "(");
p->flags |= TERMP_NOSPACE;
return(1);
} else if (MDOC_HEAD != node->type)
return(1);
- /* XXX - groff shows only first parameter */
-
p->flags |= ttypes[TTYPE_FUNC_NAME];
for (n = node->child; n; n = n->next) {
assert(MDOC_TEXT == n->type);
{
const struct mdoc_node *n;
- if (MDOC_HEAD == node->type) {
+ if (MDOC_HEAD == node->type)
return(0);
- } else if (MDOC_BLOCK != node->type)
+ else if (MDOC_BLOCK != node->type)
return(1);
if (NULL == (n = node->head->child)) {
if (arg_hasattr(MDOC_Emphasis, node))
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
+ pair->flag |= ttypes[TTYPE_EMPH];
else if (arg_hasattr(MDOC_Symbolic, node))
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
+ pair->flag |= ttypes[TTYPE_SYMB];
return(1);
}
assert(MDOC_TEXT == n->type);
if (0 == strcmp("Em", n->string))
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
+ pair->flag |= ttypes[TTYPE_EMPH];
else if (0 == strcmp("Sy", n->string))
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
+ pair->flag |= ttypes[TTYPE_SYMB];
return(1);
}
termp_sy_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
+ pair->flag |= ttypes[TTYPE_SYMB];
return(1);
}
termp_ms_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMBOL]);
+ pair->flag |= ttypes[TTYPE_SYMBOL];
return(1);
}
termp__j_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_REF_JOURNAL]);
+ pair->flag |= ttypes[TTYPE_REF_JOURNAL];
return(1);
}
n = node->child;
if (NULL == n->next) {
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK_ANCHOR]);
+ pair->flag |= ttypes[TTYPE_LINK_ANCHOR];
return(1);
}
termp_mt_pre(DECL_ARGS)
{
- TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK_ANCHOR]);
+ pair->flag |= ttypes[TTYPE_LINK_ANCHOR];
return(1);
}