1*698f87a4SGarrett D'Amore /* $Id: mdoc_term.c,v 1.258 2013/12/25 21:24:12 schwarze Exp $ */
295c635efSGarrett D'Amore /*
395c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4*698f87a4SGarrett D'Amore * Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
5*698f87a4SGarrett D'Amore * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
695c635efSGarrett D'Amore *
795c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any
895c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above
995c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies.
1095c635efSGarrett D'Amore *
1195c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1295c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1395c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1495c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1595c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1695c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1795c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1895c635efSGarrett D'Amore */
1995c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H
2095c635efSGarrett D'Amore #include "config.h"
2195c635efSGarrett D'Amore #endif
2295c635efSGarrett D'Amore
2395c635efSGarrett D'Amore #include <sys/types.h>
2495c635efSGarrett D'Amore
2595c635efSGarrett D'Amore #include <assert.h>
2695c635efSGarrett D'Amore #include <ctype.h>
2795c635efSGarrett D'Amore #include <stdint.h>
2895c635efSGarrett D'Amore #include <stdio.h>
2995c635efSGarrett D'Amore #include <stdlib.h>
3095c635efSGarrett D'Amore #include <string.h>
3195c635efSGarrett D'Amore
3295c635efSGarrett D'Amore #include "mandoc.h"
3395c635efSGarrett D'Amore #include "out.h"
3495c635efSGarrett D'Amore #include "term.h"
3595c635efSGarrett D'Amore #include "mdoc.h"
3695c635efSGarrett D'Amore #include "main.h"
3795c635efSGarrett D'Amore
3895c635efSGarrett D'Amore struct termpair {
3995c635efSGarrett D'Amore struct termpair *ppair;
4095c635efSGarrett D'Amore int count;
4195c635efSGarrett D'Amore };
4295c635efSGarrett D'Amore
4395c635efSGarrett D'Amore #define DECL_ARGS struct termp *p, \
4495c635efSGarrett D'Amore struct termpair *pair, \
45*698f87a4SGarrett D'Amore const struct mdoc_meta *meta, \
46*698f87a4SGarrett D'Amore struct mdoc_node *n
4795c635efSGarrett D'Amore
4895c635efSGarrett D'Amore struct termact {
4995c635efSGarrett D'Amore int (*pre)(DECL_ARGS);
5095c635efSGarrett D'Amore void (*post)(DECL_ARGS);
5195c635efSGarrett D'Amore };
5295c635efSGarrett D'Amore
5395c635efSGarrett D'Amore static size_t a2width(const struct termp *, const char *);
5495c635efSGarrett D'Amore static size_t a2height(const struct termp *, const char *);
5595c635efSGarrett D'Amore static size_t a2offs(const struct termp *, const char *);
5695c635efSGarrett D'Amore
5795c635efSGarrett D'Amore static void print_bvspace(struct termp *,
5895c635efSGarrett D'Amore const struct mdoc_node *,
5995c635efSGarrett D'Amore const struct mdoc_node *);
6095c635efSGarrett D'Amore static void print_mdoc_node(DECL_ARGS);
6195c635efSGarrett D'Amore static void print_mdoc_nodelist(DECL_ARGS);
6295c635efSGarrett D'Amore static void print_mdoc_head(struct termp *, const void *);
6395c635efSGarrett D'Amore static void print_mdoc_foot(struct termp *, const void *);
6495c635efSGarrett D'Amore static void synopsis_pre(struct termp *,
6595c635efSGarrett D'Amore const struct mdoc_node *);
6695c635efSGarrett D'Amore
6795c635efSGarrett D'Amore static void termp____post(DECL_ARGS);
6895c635efSGarrett D'Amore static void termp__t_post(DECL_ARGS);
6995c635efSGarrett D'Amore static void termp_an_post(DECL_ARGS);
7095c635efSGarrett D'Amore static void termp_bd_post(DECL_ARGS);
7195c635efSGarrett D'Amore static void termp_bk_post(DECL_ARGS);
7295c635efSGarrett D'Amore static void termp_bl_post(DECL_ARGS);
73*698f87a4SGarrett D'Amore static void termp_fd_post(DECL_ARGS);
7495c635efSGarrett D'Amore static void termp_fo_post(DECL_ARGS);
7595c635efSGarrett D'Amore static void termp_in_post(DECL_ARGS);
7695c635efSGarrett D'Amore static void termp_it_post(DECL_ARGS);
7795c635efSGarrett D'Amore static void termp_lb_post(DECL_ARGS);
7895c635efSGarrett D'Amore static void termp_nm_post(DECL_ARGS);
7995c635efSGarrett D'Amore static void termp_pf_post(DECL_ARGS);
8095c635efSGarrett D'Amore static void termp_quote_post(DECL_ARGS);
8195c635efSGarrett D'Amore static void termp_sh_post(DECL_ARGS);
8295c635efSGarrett D'Amore static void termp_ss_post(DECL_ARGS);
8395c635efSGarrett D'Amore
8495c635efSGarrett D'Amore static int termp__a_pre(DECL_ARGS);
8595c635efSGarrett D'Amore static int termp__t_pre(DECL_ARGS);
8695c635efSGarrett D'Amore static int termp_an_pre(DECL_ARGS);
8795c635efSGarrett D'Amore static int termp_ap_pre(DECL_ARGS);
8895c635efSGarrett D'Amore static int termp_bd_pre(DECL_ARGS);
8995c635efSGarrett D'Amore static int termp_bf_pre(DECL_ARGS);
9095c635efSGarrett D'Amore static int termp_bk_pre(DECL_ARGS);
9195c635efSGarrett D'Amore static int termp_bl_pre(DECL_ARGS);
9295c635efSGarrett D'Amore static int termp_bold_pre(DECL_ARGS);
9395c635efSGarrett D'Amore static int termp_bt_pre(DECL_ARGS);
9495c635efSGarrett D'Amore static int termp_bx_pre(DECL_ARGS);
9595c635efSGarrett D'Amore static int termp_cd_pre(DECL_ARGS);
9695c635efSGarrett D'Amore static int termp_d1_pre(DECL_ARGS);
9795c635efSGarrett D'Amore static int termp_ex_pre(DECL_ARGS);
9895c635efSGarrett D'Amore static int termp_fa_pre(DECL_ARGS);
9995c635efSGarrett D'Amore static int termp_fd_pre(DECL_ARGS);
10095c635efSGarrett D'Amore static int termp_fl_pre(DECL_ARGS);
10195c635efSGarrett D'Amore static int termp_fn_pre(DECL_ARGS);
10295c635efSGarrett D'Amore static int termp_fo_pre(DECL_ARGS);
10395c635efSGarrett D'Amore static int termp_ft_pre(DECL_ARGS);
10495c635efSGarrett D'Amore static int termp_in_pre(DECL_ARGS);
10595c635efSGarrett D'Amore static int termp_it_pre(DECL_ARGS);
10695c635efSGarrett D'Amore static int termp_li_pre(DECL_ARGS);
10795c635efSGarrett D'Amore static int termp_lk_pre(DECL_ARGS);
10895c635efSGarrett D'Amore static int termp_nd_pre(DECL_ARGS);
10995c635efSGarrett D'Amore static int termp_nm_pre(DECL_ARGS);
11095c635efSGarrett D'Amore static int termp_ns_pre(DECL_ARGS);
11195c635efSGarrett D'Amore static int termp_quote_pre(DECL_ARGS);
11295c635efSGarrett D'Amore static int termp_rs_pre(DECL_ARGS);
11395c635efSGarrett D'Amore static int termp_rv_pre(DECL_ARGS);
11495c635efSGarrett D'Amore static int termp_sh_pre(DECL_ARGS);
11595c635efSGarrett D'Amore static int termp_sm_pre(DECL_ARGS);
11695c635efSGarrett D'Amore static int termp_sp_pre(DECL_ARGS);
11795c635efSGarrett D'Amore static int termp_ss_pre(DECL_ARGS);
11895c635efSGarrett D'Amore static int termp_under_pre(DECL_ARGS);
11995c635efSGarrett D'Amore static int termp_ud_pre(DECL_ARGS);
12095c635efSGarrett D'Amore static int termp_vt_pre(DECL_ARGS);
12195c635efSGarrett D'Amore static int termp_xr_pre(DECL_ARGS);
12295c635efSGarrett D'Amore static int termp_xx_pre(DECL_ARGS);
12395c635efSGarrett D'Amore
12495c635efSGarrett D'Amore static const struct termact termacts[MDOC_MAX] = {
12595c635efSGarrett D'Amore { termp_ap_pre, NULL }, /* Ap */
12695c635efSGarrett D'Amore { NULL, NULL }, /* Dd */
12795c635efSGarrett D'Amore { NULL, NULL }, /* Dt */
12895c635efSGarrett D'Amore { NULL, NULL }, /* Os */
12995c635efSGarrett D'Amore { termp_sh_pre, termp_sh_post }, /* Sh */
13095c635efSGarrett D'Amore { termp_ss_pre, termp_ss_post }, /* Ss */
13195c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Pp */
132*698f87a4SGarrett D'Amore { termp_d1_pre, termp_bl_post }, /* D1 */
133*698f87a4SGarrett D'Amore { termp_d1_pre, termp_bl_post }, /* Dl */
13495c635efSGarrett D'Amore { termp_bd_pre, termp_bd_post }, /* Bd */
13595c635efSGarrett D'Amore { NULL, NULL }, /* Ed */
13695c635efSGarrett D'Amore { termp_bl_pre, termp_bl_post }, /* Bl */
13795c635efSGarrett D'Amore { NULL, NULL }, /* El */
13895c635efSGarrett D'Amore { termp_it_pre, termp_it_post }, /* It */
13995c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ad */
14095c635efSGarrett D'Amore { termp_an_pre, termp_an_post }, /* An */
14195c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ar */
14295c635efSGarrett D'Amore { termp_cd_pre, NULL }, /* Cd */
14395c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Cm */
14495c635efSGarrett D'Amore { NULL, NULL }, /* Dv */
14595c635efSGarrett D'Amore { NULL, NULL }, /* Er */
14695c635efSGarrett D'Amore { NULL, NULL }, /* Ev */
14795c635efSGarrett D'Amore { termp_ex_pre, NULL }, /* Ex */
14895c635efSGarrett D'Amore { termp_fa_pre, NULL }, /* Fa */
149*698f87a4SGarrett D'Amore { termp_fd_pre, termp_fd_post }, /* Fd */
15095c635efSGarrett D'Amore { termp_fl_pre, NULL }, /* Fl */
15195c635efSGarrett D'Amore { termp_fn_pre, NULL }, /* Fn */
15295c635efSGarrett D'Amore { termp_ft_pre, NULL }, /* Ft */
15395c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ic */
15495c635efSGarrett D'Amore { termp_in_pre, termp_in_post }, /* In */
15595c635efSGarrett D'Amore { termp_li_pre, NULL }, /* Li */
15695c635efSGarrett D'Amore { termp_nd_pre, NULL }, /* Nd */
15795c635efSGarrett D'Amore { termp_nm_pre, termp_nm_post }, /* Nm */
15895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Op */
15995c635efSGarrett D'Amore { NULL, NULL }, /* Ot */
16095c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Pa */
16195c635efSGarrett D'Amore { termp_rv_pre, NULL }, /* Rv */
16295c635efSGarrett D'Amore { NULL, NULL }, /* St */
16395c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Va */
16495c635efSGarrett D'Amore { termp_vt_pre, NULL }, /* Vt */
16595c635efSGarrett D'Amore { termp_xr_pre, NULL }, /* Xr */
16695c635efSGarrett D'Amore { termp__a_pre, termp____post }, /* %A */
16795c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %B */
16895c635efSGarrett D'Amore { NULL, termp____post }, /* %D */
16995c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %I */
17095c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %J */
17195c635efSGarrett D'Amore { NULL, termp____post }, /* %N */
17295c635efSGarrett D'Amore { NULL, termp____post }, /* %O */
17395c635efSGarrett D'Amore { NULL, termp____post }, /* %P */
17495c635efSGarrett D'Amore { NULL, termp____post }, /* %R */
17595c635efSGarrett D'Amore { termp__t_pre, termp__t_post }, /* %T */
17695c635efSGarrett D'Amore { NULL, termp____post }, /* %V */
17795c635efSGarrett D'Amore { NULL, NULL }, /* Ac */
17895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ao */
17995c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Aq */
18095c635efSGarrett D'Amore { NULL, NULL }, /* At */
18195c635efSGarrett D'Amore { NULL, NULL }, /* Bc */
18295c635efSGarrett D'Amore { termp_bf_pre, NULL }, /* Bf */
18395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bo */
18495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bq */
18595c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Bsx */
18695c635efSGarrett D'Amore { termp_bx_pre, NULL }, /* Bx */
18795c635efSGarrett D'Amore { NULL, NULL }, /* Db */
18895c635efSGarrett D'Amore { NULL, NULL }, /* Dc */
18995c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Do */
19095c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Dq */
19195c635efSGarrett D'Amore { NULL, NULL }, /* Ec */ /* FIXME: no space */
19295c635efSGarrett D'Amore { NULL, NULL }, /* Ef */
19395c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Em */
19495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Eo */
19595c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Fx */
19695c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ms */
197*698f87a4SGarrett D'Amore { NULL, NULL }, /* No */
19895c635efSGarrett D'Amore { termp_ns_pre, NULL }, /* Ns */
19995c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Nx */
20095c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ox */
20195c635efSGarrett D'Amore { NULL, NULL }, /* Pc */
202*698f87a4SGarrett D'Amore { NULL, termp_pf_post }, /* Pf */
20395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Po */
20495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Pq */
20595c635efSGarrett D'Amore { NULL, NULL }, /* Qc */
20695c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ql */
20795c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qo */
20895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qq */
20995c635efSGarrett D'Amore { NULL, NULL }, /* Re */
21095c635efSGarrett D'Amore { termp_rs_pre, NULL }, /* Rs */
21195c635efSGarrett D'Amore { NULL, NULL }, /* Sc */
21295c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* So */
21395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Sq */
21495c635efSGarrett D'Amore { termp_sm_pre, NULL }, /* Sm */
21595c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Sx */
21695c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Sy */
21795c635efSGarrett D'Amore { NULL, NULL }, /* Tn */
21895c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ux */
21995c635efSGarrett D'Amore { NULL, NULL }, /* Xc */
22095c635efSGarrett D'Amore { NULL, NULL }, /* Xo */
22195c635efSGarrett D'Amore { termp_fo_pre, termp_fo_post }, /* Fo */
22295c635efSGarrett D'Amore { NULL, NULL }, /* Fc */
22395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Oo */
22495c635efSGarrett D'Amore { NULL, NULL }, /* Oc */
22595c635efSGarrett D'Amore { termp_bk_pre, termp_bk_post }, /* Bk */
22695c635efSGarrett D'Amore { NULL, NULL }, /* Ek */
22795c635efSGarrett D'Amore { termp_bt_pre, NULL }, /* Bt */
22895c635efSGarrett D'Amore { NULL, NULL }, /* Hf */
22995c635efSGarrett D'Amore { NULL, NULL }, /* Fr */
23095c635efSGarrett D'Amore { termp_ud_pre, NULL }, /* Ud */
23195c635efSGarrett D'Amore { NULL, termp_lb_post }, /* Lb */
23295c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Lp */
23395c635efSGarrett D'Amore { termp_lk_pre, NULL }, /* Lk */
23495c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Mt */
23595c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Brq */
23695c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bro */
23795c635efSGarrett D'Amore { NULL, NULL }, /* Brc */
23895c635efSGarrett D'Amore { NULL, termp____post }, /* %C */
23995c635efSGarrett D'Amore { NULL, NULL }, /* Es */ /* TODO */
24095c635efSGarrett D'Amore { NULL, NULL }, /* En */ /* TODO */
24195c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Dx */
24295c635efSGarrett D'Amore { NULL, termp____post }, /* %Q */
24395c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* br */
24495c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* sp */
245*698f87a4SGarrett D'Amore { NULL, termp____post }, /* %U */
24695c635efSGarrett D'Amore { NULL, NULL }, /* Ta */
24795c635efSGarrett D'Amore };
24895c635efSGarrett D'Amore
24995c635efSGarrett D'Amore
25095c635efSGarrett D'Amore void
terminal_mdoc(void * arg,const struct mdoc * mdoc)25195c635efSGarrett D'Amore terminal_mdoc(void *arg, const struct mdoc *mdoc)
25295c635efSGarrett D'Amore {
25395c635efSGarrett D'Amore const struct mdoc_node *n;
254*698f87a4SGarrett D'Amore const struct mdoc_meta *meta;
25595c635efSGarrett D'Amore struct termp *p;
25695c635efSGarrett D'Amore
25795c635efSGarrett D'Amore p = (struct termp *)arg;
25895c635efSGarrett D'Amore
25995c635efSGarrett D'Amore if (0 == p->defindent)
26095c635efSGarrett D'Amore p->defindent = 5;
26195c635efSGarrett D'Amore
26295c635efSGarrett D'Amore p->overstep = 0;
26395c635efSGarrett D'Amore p->maxrmargin = p->defrmargin;
26495c635efSGarrett D'Amore p->tabwidth = term_len(p, 5);
26595c635efSGarrett D'Amore
26695c635efSGarrett D'Amore if (NULL == p->symtab)
26795c635efSGarrett D'Amore p->symtab = mchars_alloc();
26895c635efSGarrett D'Amore
26995c635efSGarrett D'Amore n = mdoc_node(mdoc);
270*698f87a4SGarrett D'Amore meta = mdoc_meta(mdoc);
27195c635efSGarrett D'Amore
272*698f87a4SGarrett D'Amore term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
27395c635efSGarrett D'Amore
27495c635efSGarrett D'Amore if (n->child)
275*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, NULL, meta, n->child);
27695c635efSGarrett D'Amore
27795c635efSGarrett D'Amore term_end(p);
27895c635efSGarrett D'Amore }
27995c635efSGarrett D'Amore
28095c635efSGarrett D'Amore
28195c635efSGarrett D'Amore static void
print_mdoc_nodelist(DECL_ARGS)28295c635efSGarrett D'Amore print_mdoc_nodelist(DECL_ARGS)
28395c635efSGarrett D'Amore {
28495c635efSGarrett D'Amore
285*698f87a4SGarrett D'Amore print_mdoc_node(p, pair, meta, n);
28695c635efSGarrett D'Amore if (n->next)
287*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, pair, meta, n->next);
28895c635efSGarrett D'Amore }
28995c635efSGarrett D'Amore
29095c635efSGarrett D'Amore
29195c635efSGarrett D'Amore /* ARGSUSED */
29295c635efSGarrett D'Amore static void
print_mdoc_node(DECL_ARGS)29395c635efSGarrett D'Amore print_mdoc_node(DECL_ARGS)
29495c635efSGarrett D'Amore {
29595c635efSGarrett D'Amore int chld;
29695c635efSGarrett D'Amore struct termpair npair;
29795c635efSGarrett D'Amore size_t offset, rmargin;
29895c635efSGarrett D'Amore
29995c635efSGarrett D'Amore chld = 1;
30095c635efSGarrett D'Amore offset = p->offset;
30195c635efSGarrett D'Amore rmargin = p->rmargin;
302*698f87a4SGarrett D'Amore n->prev_font = term_fontq(p);
30395c635efSGarrett D'Amore
30495c635efSGarrett D'Amore memset(&npair, 0, sizeof(struct termpair));
30595c635efSGarrett D'Amore npair.ppair = pair;
30695c635efSGarrett D'Amore
30795c635efSGarrett D'Amore /*
30895c635efSGarrett D'Amore * Keeps only work until the end of a line. If a keep was
30995c635efSGarrett D'Amore * invoked in a prior line, revert it to PREKEEP.
31095c635efSGarrett D'Amore */
31195c635efSGarrett D'Amore
312*698f87a4SGarrett D'Amore if (TERMP_KEEP & p->flags) {
313*698f87a4SGarrett D'Amore if (n->prev ? (n->prev->lastline != n->line) :
314*698f87a4SGarrett D'Amore (n->parent && n->parent->line != n->line)) {
31595c635efSGarrett D'Amore p->flags &= ~TERMP_KEEP;
31695c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP;
31795c635efSGarrett D'Amore }
31895c635efSGarrett D'Amore }
31995c635efSGarrett D'Amore
32095c635efSGarrett D'Amore /*
32195c635efSGarrett D'Amore * After the keep flags have been set up, we may now
32295c635efSGarrett D'Amore * produce output. Note that some pre-handlers do so.
32395c635efSGarrett D'Amore */
32495c635efSGarrett D'Amore
32595c635efSGarrett D'Amore switch (n->type) {
32695c635efSGarrett D'Amore case (MDOC_TEXT):
32795c635efSGarrett D'Amore if (' ' == *n->string && MDOC_LINE & n->flags)
32895c635efSGarrett D'Amore term_newln(p);
32995c635efSGarrett D'Amore if (MDOC_DELIMC & n->flags)
33095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
33195c635efSGarrett D'Amore term_word(p, n->string);
33295c635efSGarrett D'Amore if (MDOC_DELIMO & n->flags)
33395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
33495c635efSGarrett D'Amore break;
33595c635efSGarrett D'Amore case (MDOC_EQN):
33695c635efSGarrett D'Amore term_eqn(p, n->eqn);
33795c635efSGarrett D'Amore break;
33895c635efSGarrett D'Amore case (MDOC_TBL):
33995c635efSGarrett D'Amore term_tbl(p, n->span);
34095c635efSGarrett D'Amore break;
34195c635efSGarrett D'Amore default:
34295c635efSGarrett D'Amore if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
34395c635efSGarrett D'Amore chld = (*termacts[n->tok].pre)
344*698f87a4SGarrett D'Amore (p, &npair, meta, n);
34595c635efSGarrett D'Amore break;
34695c635efSGarrett D'Amore }
34795c635efSGarrett D'Amore
34895c635efSGarrett D'Amore if (chld && n->child)
349*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, &npair, meta, n->child);
35095c635efSGarrett D'Amore
351*698f87a4SGarrett D'Amore term_fontpopq(p,
352*698f87a4SGarrett D'Amore (ENDBODY_NOT == n->end ? n : n->pending)->prev_font);
35395c635efSGarrett D'Amore
35495c635efSGarrett D'Amore switch (n->type) {
35595c635efSGarrett D'Amore case (MDOC_TEXT):
35695c635efSGarrett D'Amore break;
35795c635efSGarrett D'Amore case (MDOC_TBL):
35895c635efSGarrett D'Amore break;
35995c635efSGarrett D'Amore case (MDOC_EQN):
36095c635efSGarrett D'Amore break;
36195c635efSGarrett D'Amore default:
36295c635efSGarrett D'Amore if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
36395c635efSGarrett D'Amore break;
364*698f87a4SGarrett D'Amore (void)(*termacts[n->tok].post)(p, &npair, meta, n);
36595c635efSGarrett D'Amore
36695c635efSGarrett D'Amore /*
36795c635efSGarrett D'Amore * Explicit end tokens not only call the post
36895c635efSGarrett D'Amore * handler, but also tell the respective block
36995c635efSGarrett D'Amore * that it must not call the post handler again.
37095c635efSGarrett D'Amore */
37195c635efSGarrett D'Amore if (ENDBODY_NOT != n->end)
37295c635efSGarrett D'Amore n->pending->flags |= MDOC_ENDED;
37395c635efSGarrett D'Amore
37495c635efSGarrett D'Amore /*
37595c635efSGarrett D'Amore * End of line terminating an implicit block
37695c635efSGarrett D'Amore * while an explicit block is still open.
37795c635efSGarrett D'Amore * Continue the explicit block without spacing.
37895c635efSGarrett D'Amore */
37995c635efSGarrett D'Amore if (ENDBODY_NOSPACE == n->end)
38095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
38195c635efSGarrett D'Amore break;
38295c635efSGarrett D'Amore }
38395c635efSGarrett D'Amore
38495c635efSGarrett D'Amore if (MDOC_EOS & n->flags)
38595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
38695c635efSGarrett D'Amore
38795c635efSGarrett D'Amore p->offset = offset;
38895c635efSGarrett D'Amore p->rmargin = rmargin;
38995c635efSGarrett D'Amore }
39095c635efSGarrett D'Amore
39195c635efSGarrett D'Amore
39295c635efSGarrett D'Amore static void
print_mdoc_foot(struct termp * p,const void * arg)39395c635efSGarrett D'Amore print_mdoc_foot(struct termp *p, const void *arg)
39495c635efSGarrett D'Amore {
395*698f87a4SGarrett D'Amore const struct mdoc_meta *meta;
39695c635efSGarrett D'Amore
397*698f87a4SGarrett D'Amore meta = (const struct mdoc_meta *)arg;
39895c635efSGarrett D'Amore
39995c635efSGarrett D'Amore term_fontrepl(p, TERMFONT_NONE);
40095c635efSGarrett D'Amore
40195c635efSGarrett D'Amore /*
40295c635efSGarrett D'Amore * Output the footer in new-groff style, that is, three columns
40395c635efSGarrett D'Amore * with the middle being the manual date and flanking columns
40495c635efSGarrett D'Amore * being the operating system:
40595c635efSGarrett D'Amore *
40695c635efSGarrett D'Amore * SYSTEM DATE SYSTEM
40795c635efSGarrett D'Amore */
40895c635efSGarrett D'Amore
40995c635efSGarrett D'Amore term_vspace(p);
41095c635efSGarrett D'Amore
41195c635efSGarrett D'Amore p->offset = 0;
41295c635efSGarrett D'Amore p->rmargin = (p->maxrmargin -
413*698f87a4SGarrett D'Amore term_strlen(p, meta->date) + term_len(p, 1)) / 2;
414*698f87a4SGarrett D'Amore p->trailspace = 1;
41595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
41695c635efSGarrett D'Amore
417*698f87a4SGarrett D'Amore term_word(p, meta->os);
41895c635efSGarrett D'Amore term_flushln(p);
41995c635efSGarrett D'Amore
42095c635efSGarrett D'Amore p->offset = p->rmargin;
421*698f87a4SGarrett D'Amore p->rmargin = p->maxrmargin - term_strlen(p, meta->os);
42295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
42395c635efSGarrett D'Amore
424*698f87a4SGarrett D'Amore term_word(p, meta->date);
42595c635efSGarrett D'Amore term_flushln(p);
42695c635efSGarrett D'Amore
42795c635efSGarrett D'Amore p->offset = p->rmargin;
42895c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
429*698f87a4SGarrett D'Amore p->trailspace = 0;
43095c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK;
43195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
43295c635efSGarrett D'Amore
433*698f87a4SGarrett D'Amore term_word(p, meta->os);
43495c635efSGarrett D'Amore term_flushln(p);
43595c635efSGarrett D'Amore
43695c635efSGarrett D'Amore p->offset = 0;
43795c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
43895c635efSGarrett D'Amore p->flags = 0;
43995c635efSGarrett D'Amore }
44095c635efSGarrett D'Amore
44195c635efSGarrett D'Amore
44295c635efSGarrett D'Amore static void
print_mdoc_head(struct termp * p,const void * arg)44395c635efSGarrett D'Amore print_mdoc_head(struct termp *p, const void *arg)
44495c635efSGarrett D'Amore {
44595c635efSGarrett D'Amore char buf[BUFSIZ], title[BUFSIZ];
44695c635efSGarrett D'Amore size_t buflen, titlen;
447*698f87a4SGarrett D'Amore const struct mdoc_meta *meta;
44895c635efSGarrett D'Amore
449*698f87a4SGarrett D'Amore meta = (const struct mdoc_meta *)arg;
45095c635efSGarrett D'Amore
45195c635efSGarrett D'Amore /*
45295c635efSGarrett D'Amore * The header is strange. It has three components, which are
45395c635efSGarrett D'Amore * really two with the first duplicated. It goes like this:
45495c635efSGarrett D'Amore *
45595c635efSGarrett D'Amore * IDENTIFIER TITLE IDENTIFIER
45695c635efSGarrett D'Amore *
45795c635efSGarrett D'Amore * The IDENTIFIER is NAME(SECTION), which is the command-name
45895c635efSGarrett D'Amore * (if given, or "unknown" if not) followed by the manual page
45995c635efSGarrett D'Amore * section. These are given in `Dt'. The TITLE is a free-form
46095c635efSGarrett D'Amore * string depending on the manual volume. If not specified, it
46195c635efSGarrett D'Amore * switches on the manual section.
46295c635efSGarrett D'Amore */
46395c635efSGarrett D'Amore
46495c635efSGarrett D'Amore p->offset = 0;
46595c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
46695c635efSGarrett D'Amore
467*698f87a4SGarrett D'Amore assert(meta->vol);
468*698f87a4SGarrett D'Amore strlcpy(buf, meta->vol, BUFSIZ);
46995c635efSGarrett D'Amore buflen = term_strlen(p, buf);
47095c635efSGarrett D'Amore
471*698f87a4SGarrett D'Amore if (meta->arch) {
47295c635efSGarrett D'Amore strlcat(buf, " (", BUFSIZ);
473*698f87a4SGarrett D'Amore strlcat(buf, meta->arch, BUFSIZ);
47495c635efSGarrett D'Amore strlcat(buf, ")", BUFSIZ);
47595c635efSGarrett D'Amore }
47695c635efSGarrett D'Amore
477*698f87a4SGarrett D'Amore snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
47895c635efSGarrett D'Amore titlen = term_strlen(p, title);
47995c635efSGarrett D'Amore
48095c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
481*698f87a4SGarrett D'Amore p->trailspace = 1;
48295c635efSGarrett D'Amore p->offset = 0;
48395c635efSGarrett D'Amore p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
48495c635efSGarrett D'Amore (p->maxrmargin -
48595c635efSGarrett D'Amore term_strlen(p, buf) + term_len(p, 1)) / 2 :
48695c635efSGarrett D'Amore p->maxrmargin - buflen;
48795c635efSGarrett D'Amore
48895c635efSGarrett D'Amore term_word(p, title);
48995c635efSGarrett D'Amore term_flushln(p);
49095c635efSGarrett D'Amore
49195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
49295c635efSGarrett D'Amore p->offset = p->rmargin;
49395c635efSGarrett D'Amore p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
49495c635efSGarrett D'Amore p->maxrmargin - titlen : p->maxrmargin;
49595c635efSGarrett D'Amore
49695c635efSGarrett D'Amore term_word(p, buf);
49795c635efSGarrett D'Amore term_flushln(p);
49895c635efSGarrett D'Amore
49995c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK;
500*698f87a4SGarrett D'Amore p->trailspace = 0;
50195c635efSGarrett D'Amore if (p->rmargin + titlen <= p->maxrmargin) {
50295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
50395c635efSGarrett D'Amore p->offset = p->rmargin;
50495c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
50595c635efSGarrett D'Amore term_word(p, title);
50695c635efSGarrett D'Amore term_flushln(p);
50795c635efSGarrett D'Amore }
50895c635efSGarrett D'Amore
50995c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE;
51095c635efSGarrett D'Amore p->offset = 0;
51195c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
51295c635efSGarrett D'Amore }
51395c635efSGarrett D'Amore
51495c635efSGarrett D'Amore
51595c635efSGarrett D'Amore static size_t
a2height(const struct termp * p,const char * v)51695c635efSGarrett D'Amore a2height(const struct termp *p, const char *v)
51795c635efSGarrett D'Amore {
51895c635efSGarrett D'Amore struct roffsu su;
51995c635efSGarrett D'Amore
52095c635efSGarrett D'Amore
52195c635efSGarrett D'Amore assert(v);
52295c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_VS))
52395c635efSGarrett D'Amore SCALE_VS_INIT(&su, atoi(v));
52495c635efSGarrett D'Amore
52595c635efSGarrett D'Amore return(term_vspan(p, &su));
52695c635efSGarrett D'Amore }
52795c635efSGarrett D'Amore
52895c635efSGarrett D'Amore
52995c635efSGarrett D'Amore static size_t
a2width(const struct termp * p,const char * v)53095c635efSGarrett D'Amore a2width(const struct termp *p, const char *v)
53195c635efSGarrett D'Amore {
53295c635efSGarrett D'Amore struct roffsu su;
53395c635efSGarrett D'Amore
53495c635efSGarrett D'Amore assert(v);
53595c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_MAX))
53695c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v));
53795c635efSGarrett D'Amore
53895c635efSGarrett D'Amore return(term_hspan(p, &su));
53995c635efSGarrett D'Amore }
54095c635efSGarrett D'Amore
54195c635efSGarrett D'Amore
54295c635efSGarrett D'Amore static size_t
a2offs(const struct termp * p,const char * v)54395c635efSGarrett D'Amore a2offs(const struct termp *p, const char *v)
54495c635efSGarrett D'Amore {
54595c635efSGarrett D'Amore struct roffsu su;
54695c635efSGarrett D'Amore
54795c635efSGarrett D'Amore if ('\0' == *v)
54895c635efSGarrett D'Amore return(0);
54995c635efSGarrett D'Amore else if (0 == strcmp(v, "left"))
55095c635efSGarrett D'Amore return(0);
55195c635efSGarrett D'Amore else if (0 == strcmp(v, "indent"))
55295c635efSGarrett D'Amore return(term_len(p, p->defindent + 1));
55395c635efSGarrett D'Amore else if (0 == strcmp(v, "indent-two"))
55495c635efSGarrett D'Amore return(term_len(p, (p->defindent + 1) * 2));
55595c635efSGarrett D'Amore else if ( ! a2roffsu(v, &su, SCALE_MAX))
55695c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v));
55795c635efSGarrett D'Amore
55895c635efSGarrett D'Amore return(term_hspan(p, &su));
55995c635efSGarrett D'Amore }
56095c635efSGarrett D'Amore
56195c635efSGarrett D'Amore
56295c635efSGarrett D'Amore /*
56395c635efSGarrett D'Amore * Determine how much space to print out before block elements of `It'
56495c635efSGarrett D'Amore * (and thus `Bl') and `Bd'. And then go ahead and print that space,
56595c635efSGarrett D'Amore * too.
56695c635efSGarrett D'Amore */
56795c635efSGarrett D'Amore static void
print_bvspace(struct termp * p,const struct mdoc_node * bl,const struct mdoc_node * n)56895c635efSGarrett D'Amore print_bvspace(struct termp *p,
56995c635efSGarrett D'Amore const struct mdoc_node *bl,
57095c635efSGarrett D'Amore const struct mdoc_node *n)
57195c635efSGarrett D'Amore {
57295c635efSGarrett D'Amore const struct mdoc_node *nn;
57395c635efSGarrett D'Amore
57495c635efSGarrett D'Amore assert(n);
57595c635efSGarrett D'Amore
57695c635efSGarrett D'Amore term_newln(p);
57795c635efSGarrett D'Amore
57895c635efSGarrett D'Amore if (MDOC_Bd == bl->tok && bl->norm->Bd.comp)
57995c635efSGarrett D'Amore return;
58095c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && bl->norm->Bl.comp)
58195c635efSGarrett D'Amore return;
58295c635efSGarrett D'Amore
58395c635efSGarrett D'Amore /* Do not vspace directly after Ss/Sh. */
58495c635efSGarrett D'Amore
58595c635efSGarrett D'Amore for (nn = n; nn; nn = nn->parent) {
58695c635efSGarrett D'Amore if (MDOC_BLOCK != nn->type)
58795c635efSGarrett D'Amore continue;
58895c635efSGarrett D'Amore if (MDOC_Ss == nn->tok)
58995c635efSGarrett D'Amore return;
59095c635efSGarrett D'Amore if (MDOC_Sh == nn->tok)
59195c635efSGarrett D'Amore return;
59295c635efSGarrett D'Amore if (NULL == nn->prev)
59395c635efSGarrett D'Amore continue;
59495c635efSGarrett D'Amore break;
59595c635efSGarrett D'Amore }
59695c635efSGarrett D'Amore
59795c635efSGarrett D'Amore /* A `-column' does not assert vspace within the list. */
59895c635efSGarrett D'Amore
59995c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type)
60095c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok)
60195c635efSGarrett D'Amore return;
60295c635efSGarrett D'Amore
60395c635efSGarrett D'Amore /* A `-diag' without body does not vspace. */
60495c635efSGarrett D'Amore
60595c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type)
60695c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok) {
60795c635efSGarrett D'Amore assert(n->prev->body);
60895c635efSGarrett D'Amore if (NULL == n->prev->body->child)
60995c635efSGarrett D'Amore return;
61095c635efSGarrett D'Amore }
61195c635efSGarrett D'Amore
61295c635efSGarrett D'Amore term_vspace(p);
61395c635efSGarrett D'Amore }
61495c635efSGarrett D'Amore
61595c635efSGarrett D'Amore
61695c635efSGarrett D'Amore /* ARGSUSED */
61795c635efSGarrett D'Amore static int
termp_it_pre(DECL_ARGS)61895c635efSGarrett D'Amore termp_it_pre(DECL_ARGS)
61995c635efSGarrett D'Amore {
62095c635efSGarrett D'Amore const struct mdoc_node *bl, *nn;
62195c635efSGarrett D'Amore char buf[7];
62295c635efSGarrett D'Amore int i;
62395c635efSGarrett D'Amore size_t width, offset, ncols, dcol;
62495c635efSGarrett D'Amore enum mdoc_list type;
62595c635efSGarrett D'Amore
62695c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) {
62795c635efSGarrett D'Amore print_bvspace(p, n->parent->parent, n);
62895c635efSGarrett D'Amore return(1);
62995c635efSGarrett D'Amore }
63095c635efSGarrett D'Amore
63195c635efSGarrett D'Amore bl = n->parent->parent->parent;
63295c635efSGarrett D'Amore type = bl->norm->Bl.type;
63395c635efSGarrett D'Amore
63495c635efSGarrett D'Amore /*
63595c635efSGarrett D'Amore * First calculate width and offset. This is pretty easy unless
63695c635efSGarrett D'Amore * we're a -column list, in which case all prior columns must
63795c635efSGarrett D'Amore * be accounted for.
63895c635efSGarrett D'Amore */
63995c635efSGarrett D'Amore
64095c635efSGarrett D'Amore width = offset = 0;
64195c635efSGarrett D'Amore
64295c635efSGarrett D'Amore if (bl->norm->Bl.offs)
64395c635efSGarrett D'Amore offset = a2offs(p, bl->norm->Bl.offs);
64495c635efSGarrett D'Amore
64595c635efSGarrett D'Amore switch (type) {
64695c635efSGarrett D'Amore case (LIST_column):
64795c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
64895c635efSGarrett D'Amore break;
64995c635efSGarrett D'Amore
65095c635efSGarrett D'Amore /*
65195c635efSGarrett D'Amore * Imitate groff's column handling:
65295c635efSGarrett D'Amore * - For each earlier column, add its width.
65395c635efSGarrett D'Amore * - For less than 5 columns, add four more blanks per
65495c635efSGarrett D'Amore * column.
65595c635efSGarrett D'Amore * - For exactly 5 columns, add three more blank per
65695c635efSGarrett D'Amore * column.
65795c635efSGarrett D'Amore * - For more than 5 columns, add only one column.
65895c635efSGarrett D'Amore */
65995c635efSGarrett D'Amore ncols = bl->norm->Bl.ncols;
66095c635efSGarrett D'Amore
66195c635efSGarrett D'Amore /* LINTED */
66295c635efSGarrett D'Amore dcol = ncols < 5 ? term_len(p, 4) :
66395c635efSGarrett D'Amore ncols == 5 ? term_len(p, 3) : term_len(p, 1);
66495c635efSGarrett D'Amore
66595c635efSGarrett D'Amore /*
66695c635efSGarrett D'Amore * Calculate the offset by applying all prior MDOC_BODY,
66795c635efSGarrett D'Amore * so we stop at the MDOC_HEAD (NULL == nn->prev).
66895c635efSGarrett D'Amore */
66995c635efSGarrett D'Amore
67095c635efSGarrett D'Amore for (i = 0, nn = n->prev;
67195c635efSGarrett D'Amore nn->prev && i < (int)ncols;
67295c635efSGarrett D'Amore nn = nn->prev, i++)
67395c635efSGarrett D'Amore offset += dcol + a2width
67495c635efSGarrett D'Amore (p, bl->norm->Bl.cols[i]);
67595c635efSGarrett D'Amore
67695c635efSGarrett D'Amore /*
67795c635efSGarrett D'Amore * When exceeding the declared number of columns, leave
67895c635efSGarrett D'Amore * the remaining widths at 0. This will later be
67995c635efSGarrett D'Amore * adjusted to the default width of 10, or, for the last
68095c635efSGarrett D'Amore * column, stretched to the right margin.
68195c635efSGarrett D'Amore */
68295c635efSGarrett D'Amore if (i >= (int)ncols)
68395c635efSGarrett D'Amore break;
68495c635efSGarrett D'Amore
68595c635efSGarrett D'Amore /*
68695c635efSGarrett D'Amore * Use the declared column widths, extended as explained
68795c635efSGarrett D'Amore * in the preceding paragraph.
68895c635efSGarrett D'Amore */
68995c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.cols[i]) + dcol;
69095c635efSGarrett D'Amore break;
69195c635efSGarrett D'Amore default:
69295c635efSGarrett D'Amore if (NULL == bl->norm->Bl.width)
69395c635efSGarrett D'Amore break;
69495c635efSGarrett D'Amore
69595c635efSGarrett D'Amore /*
69695c635efSGarrett D'Amore * Note: buffer the width by 2, which is groff's magic
69795c635efSGarrett D'Amore * number for buffering single arguments. See the above
69895c635efSGarrett D'Amore * handling for column for how this changes.
69995c635efSGarrett D'Amore */
70095c635efSGarrett D'Amore assert(bl->norm->Bl.width);
70195c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.width) + term_len(p, 2);
70295c635efSGarrett D'Amore break;
70395c635efSGarrett D'Amore }
70495c635efSGarrett D'Amore
70595c635efSGarrett D'Amore /*
70695c635efSGarrett D'Amore * List-type can override the width in the case of fixed-head
70795c635efSGarrett D'Amore * values (bullet, dash/hyphen, enum). Tags need a non-zero
70895c635efSGarrett D'Amore * offset.
70995c635efSGarrett D'Amore */
71095c635efSGarrett D'Amore
71195c635efSGarrett D'Amore switch (type) {
71295c635efSGarrett D'Amore case (LIST_bullet):
71395c635efSGarrett D'Amore /* FALLTHROUGH */
71495c635efSGarrett D'Amore case (LIST_dash):
71595c635efSGarrett D'Amore /* FALLTHROUGH */
71695c635efSGarrett D'Amore case (LIST_hyphen):
717*698f87a4SGarrett D'Amore /* FALLTHROUGH */
71895c635efSGarrett D'Amore case (LIST_enum):
719*698f87a4SGarrett D'Amore if (width < term_len(p, 2))
720*698f87a4SGarrett D'Amore width = term_len(p, 2);
72195c635efSGarrett D'Amore break;
72295c635efSGarrett D'Amore case (LIST_hang):
72395c635efSGarrett D'Amore if (0 == width)
72495c635efSGarrett D'Amore width = term_len(p, 8);
72595c635efSGarrett D'Amore break;
72695c635efSGarrett D'Amore case (LIST_column):
72795c635efSGarrett D'Amore /* FALLTHROUGH */
72895c635efSGarrett D'Amore case (LIST_tag):
72995c635efSGarrett D'Amore if (0 == width)
73095c635efSGarrett D'Amore width = term_len(p, 10);
73195c635efSGarrett D'Amore break;
73295c635efSGarrett D'Amore default:
73395c635efSGarrett D'Amore break;
73495c635efSGarrett D'Amore }
73595c635efSGarrett D'Amore
73695c635efSGarrett D'Amore /*
73795c635efSGarrett D'Amore * Whitespace control. Inset bodies need an initial space,
73895c635efSGarrett D'Amore * while diagonal bodies need two.
73995c635efSGarrett D'Amore */
74095c635efSGarrett D'Amore
74195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
74295c635efSGarrett D'Amore
74395c635efSGarrett D'Amore switch (type) {
74495c635efSGarrett D'Amore case (LIST_diag):
74595c635efSGarrett D'Amore if (MDOC_BODY == n->type)
74695c635efSGarrett D'Amore term_word(p, "\\ \\ ");
74795c635efSGarrett D'Amore break;
74895c635efSGarrett D'Amore case (LIST_inset):
74995c635efSGarrett D'Amore if (MDOC_BODY == n->type)
75095c635efSGarrett D'Amore term_word(p, "\\ ");
75195c635efSGarrett D'Amore break;
75295c635efSGarrett D'Amore default:
75395c635efSGarrett D'Amore break;
75495c635efSGarrett D'Amore }
75595c635efSGarrett D'Amore
75695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
75795c635efSGarrett D'Amore
75895c635efSGarrett D'Amore switch (type) {
75995c635efSGarrett D'Amore case (LIST_diag):
76095c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
76195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
76295c635efSGarrett D'Amore break;
76395c635efSGarrett D'Amore default:
76495c635efSGarrett D'Amore break;
76595c635efSGarrett D'Amore }
76695c635efSGarrett D'Amore
76795c635efSGarrett D'Amore /*
76895c635efSGarrett D'Amore * Pad and break control. This is the tricky part. These flags
76995c635efSGarrett D'Amore * are documented in term_flushln() in term.c. Note that we're
77095c635efSGarrett D'Amore * going to unset all of these flags in termp_it_post() when we
77195c635efSGarrett D'Amore * exit.
77295c635efSGarrett D'Amore */
77395c635efSGarrett D'Amore
77495c635efSGarrett D'Amore switch (type) {
775*698f87a4SGarrett D'Amore case (LIST_enum):
776*698f87a4SGarrett D'Amore /*
777*698f87a4SGarrett D'Amore * Weird special case.
778*698f87a4SGarrett D'Amore * Very narrow enum lists actually hang.
779*698f87a4SGarrett D'Amore */
780*698f87a4SGarrett D'Amore if (width == term_len(p, 2))
781*698f87a4SGarrett D'Amore p->flags |= TERMP_HANG;
782*698f87a4SGarrett D'Amore /* FALLTHROUGH */
78395c635efSGarrett D'Amore case (LIST_bullet):
78495c635efSGarrett D'Amore /* FALLTHROUGH */
78595c635efSGarrett D'Amore case (LIST_dash):
78695c635efSGarrett D'Amore /* FALLTHROUGH */
78795c635efSGarrett D'Amore case (LIST_hyphen):
788*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type)
789*698f87a4SGarrett D'Amore break;
79095c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK;
791*698f87a4SGarrett D'Amore p->trailspace = 1;
79295c635efSGarrett D'Amore break;
79395c635efSGarrett D'Amore case (LIST_hang):
794*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type)
79595c635efSGarrett D'Amore break;
79695c635efSGarrett D'Amore
79795c635efSGarrett D'Amore /*
79895c635efSGarrett D'Amore * This is ugly. If `-hang' is specified and the body
79995c635efSGarrett D'Amore * is a `Bl' or `Bd', then we want basically to nullify
80095c635efSGarrett D'Amore * the "overstep" effect in term_flushln() and treat
80195c635efSGarrett D'Amore * this as a `-ohang' list instead.
80295c635efSGarrett D'Amore */
80395c635efSGarrett D'Amore if (n->next->child &&
80495c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok ||
80595c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok))
806*698f87a4SGarrett D'Amore break;
807*698f87a4SGarrett D'Amore
808*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG;
809*698f87a4SGarrett D'Amore p->trailspace = 1;
81095c635efSGarrett D'Amore break;
81195c635efSGarrett D'Amore case (LIST_tag):
81295c635efSGarrett D'Amore if (MDOC_HEAD != n->type)
81395c635efSGarrett D'Amore break;
814*698f87a4SGarrett D'Amore
815*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK;
816*698f87a4SGarrett D'Amore p->trailspace = 2;
817*698f87a4SGarrett D'Amore
81895c635efSGarrett D'Amore if (NULL == n->next || NULL == n->next->child)
81995c635efSGarrett D'Amore p->flags |= TERMP_DANGLE;
82095c635efSGarrett D'Amore break;
82195c635efSGarrett D'Amore case (LIST_column):
82295c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
82395c635efSGarrett D'Amore break;
82495c635efSGarrett D'Amore
825*698f87a4SGarrett D'Amore if (NULL == n->next) {
82695c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK;
827*698f87a4SGarrett D'Amore p->trailspace = 0;
828*698f87a4SGarrett D'Amore } else {
82995c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK;
830*698f87a4SGarrett D'Amore p->trailspace = 1;
831*698f87a4SGarrett D'Amore }
83295c635efSGarrett D'Amore
83395c635efSGarrett D'Amore break;
83495c635efSGarrett D'Amore case (LIST_diag):
835*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type)
836*698f87a4SGarrett D'Amore break;
83795c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK;
838*698f87a4SGarrett D'Amore p->trailspace = 1;
83995c635efSGarrett D'Amore break;
84095c635efSGarrett D'Amore default:
84195c635efSGarrett D'Amore break;
84295c635efSGarrett D'Amore }
84395c635efSGarrett D'Amore
84495c635efSGarrett D'Amore /*
84595c635efSGarrett D'Amore * Margin control. Set-head-width lists have their right
84695c635efSGarrett D'Amore * margins shortened. The body for these lists has the offset
84795c635efSGarrett D'Amore * necessarily lengthened. Everybody gets the offset.
84895c635efSGarrett D'Amore */
84995c635efSGarrett D'Amore
85095c635efSGarrett D'Amore p->offset += offset;
85195c635efSGarrett D'Amore
85295c635efSGarrett D'Amore switch (type) {
85395c635efSGarrett D'Amore case (LIST_hang):
85495c635efSGarrett D'Amore /*
85595c635efSGarrett D'Amore * Same stipulation as above, regarding `-hang'. We
85695c635efSGarrett D'Amore * don't want to recalculate rmargin and offsets when
85795c635efSGarrett D'Amore * using `Bd' or `Bl' within `-hang' overstep lists.
85895c635efSGarrett D'Amore */
85995c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child &&
86095c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok ||
86195c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok))
86295c635efSGarrett D'Amore break;
86395c635efSGarrett D'Amore /* FALLTHROUGH */
86495c635efSGarrett D'Amore case (LIST_bullet):
86595c635efSGarrett D'Amore /* FALLTHROUGH */
86695c635efSGarrett D'Amore case (LIST_dash):
86795c635efSGarrett D'Amore /* FALLTHROUGH */
86895c635efSGarrett D'Amore case (LIST_enum):
86995c635efSGarrett D'Amore /* FALLTHROUGH */
87095c635efSGarrett D'Amore case (LIST_hyphen):
87195c635efSGarrett D'Amore /* FALLTHROUGH */
87295c635efSGarrett D'Amore case (LIST_tag):
87395c635efSGarrett D'Amore assert(width);
87495c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
87595c635efSGarrett D'Amore p->rmargin = p->offset + width;
87695c635efSGarrett D'Amore else
87795c635efSGarrett D'Amore p->offset += width;
87895c635efSGarrett D'Amore break;
87995c635efSGarrett D'Amore case (LIST_column):
88095c635efSGarrett D'Amore assert(width);
88195c635efSGarrett D'Amore p->rmargin = p->offset + width;
88295c635efSGarrett D'Amore /*
88395c635efSGarrett D'Amore * XXX - this behaviour is not documented: the
88495c635efSGarrett D'Amore * right-most column is filled to the right margin.
88595c635efSGarrett D'Amore */
88695c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
88795c635efSGarrett D'Amore break;
88895c635efSGarrett D'Amore if (NULL == n->next && p->rmargin < p->maxrmargin)
88995c635efSGarrett D'Amore p->rmargin = p->maxrmargin;
89095c635efSGarrett D'Amore break;
89195c635efSGarrett D'Amore default:
89295c635efSGarrett D'Amore break;
89395c635efSGarrett D'Amore }
89495c635efSGarrett D'Amore
89595c635efSGarrett D'Amore /*
89695c635efSGarrett D'Amore * The dash, hyphen, bullet and enum lists all have a special
89795c635efSGarrett D'Amore * HEAD character (temporarily bold, in some cases).
89895c635efSGarrett D'Amore */
89995c635efSGarrett D'Amore
90095c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
90195c635efSGarrett D'Amore switch (type) {
90295c635efSGarrett D'Amore case (LIST_bullet):
90395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
90495c635efSGarrett D'Amore term_word(p, "\\[bu]");
90595c635efSGarrett D'Amore term_fontpop(p);
90695c635efSGarrett D'Amore break;
90795c635efSGarrett D'Amore case (LIST_dash):
90895c635efSGarrett D'Amore /* FALLTHROUGH */
90995c635efSGarrett D'Amore case (LIST_hyphen):
91095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
91195c635efSGarrett D'Amore term_word(p, "\\(hy");
91295c635efSGarrett D'Amore term_fontpop(p);
91395c635efSGarrett D'Amore break;
91495c635efSGarrett D'Amore case (LIST_enum):
91595c635efSGarrett D'Amore (pair->ppair->ppair->count)++;
91695c635efSGarrett D'Amore snprintf(buf, sizeof(buf), "%d.",
91795c635efSGarrett D'Amore pair->ppair->ppair->count);
91895c635efSGarrett D'Amore term_word(p, buf);
91995c635efSGarrett D'Amore break;
92095c635efSGarrett D'Amore default:
92195c635efSGarrett D'Amore break;
92295c635efSGarrett D'Amore }
92395c635efSGarrett D'Amore
92495c635efSGarrett D'Amore /*
92595c635efSGarrett D'Amore * If we're not going to process our children, indicate so here.
92695c635efSGarrett D'Amore */
92795c635efSGarrett D'Amore
92895c635efSGarrett D'Amore switch (type) {
92995c635efSGarrett D'Amore case (LIST_bullet):
93095c635efSGarrett D'Amore /* FALLTHROUGH */
93195c635efSGarrett D'Amore case (LIST_item):
93295c635efSGarrett D'Amore /* FALLTHROUGH */
93395c635efSGarrett D'Amore case (LIST_dash):
93495c635efSGarrett D'Amore /* FALLTHROUGH */
93595c635efSGarrett D'Amore case (LIST_hyphen):
93695c635efSGarrett D'Amore /* FALLTHROUGH */
93795c635efSGarrett D'Amore case (LIST_enum):
93895c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
93995c635efSGarrett D'Amore return(0);
94095c635efSGarrett D'Amore break;
94195c635efSGarrett D'Amore case (LIST_column):
94295c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
94395c635efSGarrett D'Amore return(0);
94495c635efSGarrett D'Amore break;
94595c635efSGarrett D'Amore default:
94695c635efSGarrett D'Amore break;
94795c635efSGarrett D'Amore }
94895c635efSGarrett D'Amore
94995c635efSGarrett D'Amore return(1);
95095c635efSGarrett D'Amore }
95195c635efSGarrett D'Amore
95295c635efSGarrett D'Amore
95395c635efSGarrett D'Amore /* ARGSUSED */
95495c635efSGarrett D'Amore static void
termp_it_post(DECL_ARGS)95595c635efSGarrett D'Amore termp_it_post(DECL_ARGS)
95695c635efSGarrett D'Amore {
95795c635efSGarrett D'Amore enum mdoc_list type;
95895c635efSGarrett D'Amore
95995c635efSGarrett D'Amore if (MDOC_BLOCK == n->type)
96095c635efSGarrett D'Amore return;
96195c635efSGarrett D'Amore
96295c635efSGarrett D'Amore type = n->parent->parent->parent->norm->Bl.type;
96395c635efSGarrett D'Amore
96495c635efSGarrett D'Amore switch (type) {
96595c635efSGarrett D'Amore case (LIST_item):
96695c635efSGarrett D'Amore /* FALLTHROUGH */
96795c635efSGarrett D'Amore case (LIST_diag):
96895c635efSGarrett D'Amore /* FALLTHROUGH */
96995c635efSGarrett D'Amore case (LIST_inset):
97095c635efSGarrett D'Amore if (MDOC_BODY == n->type)
97195c635efSGarrett D'Amore term_newln(p);
97295c635efSGarrett D'Amore break;
97395c635efSGarrett D'Amore case (LIST_column):
97495c635efSGarrett D'Amore if (MDOC_BODY == n->type)
97595c635efSGarrett D'Amore term_flushln(p);
97695c635efSGarrett D'Amore break;
97795c635efSGarrett D'Amore default:
97895c635efSGarrett D'Amore term_newln(p);
97995c635efSGarrett D'Amore break;
98095c635efSGarrett D'Amore }
98195c635efSGarrett D'Amore
98295c635efSGarrett D'Amore /*
98395c635efSGarrett D'Amore * Now that our output is flushed, we can reset our tags. Since
98495c635efSGarrett D'Amore * only `It' sets these flags, we're free to assume that nobody
98595c635efSGarrett D'Amore * has munged them in the meanwhile.
98695c635efSGarrett D'Amore */
98795c635efSGarrett D'Amore
98895c635efSGarrett D'Amore p->flags &= ~TERMP_DANGLE;
98995c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK;
99095c635efSGarrett D'Amore p->flags &= ~TERMP_HANG;
991*698f87a4SGarrett D'Amore p->trailspace = 0;
99295c635efSGarrett D'Amore }
99395c635efSGarrett D'Amore
99495c635efSGarrett D'Amore
99595c635efSGarrett D'Amore /* ARGSUSED */
99695c635efSGarrett D'Amore static int
termp_nm_pre(DECL_ARGS)99795c635efSGarrett D'Amore termp_nm_pre(DECL_ARGS)
99895c635efSGarrett D'Amore {
99995c635efSGarrett D'Amore
1000*698f87a4SGarrett D'Amore if (MDOC_BLOCK == n->type) {
1001*698f87a4SGarrett D'Amore p->flags |= TERMP_PREKEEP;
100295c635efSGarrett D'Amore return(1);
1003*698f87a4SGarrett D'Amore }
100495c635efSGarrett D'Amore
100595c635efSGarrett D'Amore if (MDOC_BODY == n->type) {
100695c635efSGarrett D'Amore if (NULL == n->child)
100795c635efSGarrett D'Amore return(0);
100895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
100995c635efSGarrett D'Amore p->offset += term_len(p, 1) +
1010*698f87a4SGarrett D'Amore (NULL == n->prev->child ?
1011*698f87a4SGarrett D'Amore term_strlen(p, meta->name) :
101295c635efSGarrett D'Amore MDOC_TEXT == n->prev->child->type ?
101395c635efSGarrett D'Amore term_strlen(p, n->prev->child->string) :
101495c635efSGarrett D'Amore term_len(p, 5));
101595c635efSGarrett D'Amore return(1);
101695c635efSGarrett D'Amore }
101795c635efSGarrett D'Amore
1018*698f87a4SGarrett D'Amore if (NULL == n->child && NULL == meta->name)
101995c635efSGarrett D'Amore return(0);
102095c635efSGarrett D'Amore
102195c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
102295c635efSGarrett D'Amore synopsis_pre(p, n->parent);
102395c635efSGarrett D'Amore
102495c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child) {
102595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
1026*698f87a4SGarrett D'Amore p->trailspace = 1;
102795c635efSGarrett D'Amore p->rmargin = p->offset + term_len(p, 1);
102895c635efSGarrett D'Amore if (NULL == n->child) {
1029*698f87a4SGarrett D'Amore p->rmargin += term_strlen(p, meta->name);
103095c635efSGarrett D'Amore } else if (MDOC_TEXT == n->child->type) {
103195c635efSGarrett D'Amore p->rmargin += term_strlen(p, n->child->string);
103295c635efSGarrett D'Amore if (n->child->next)
103395c635efSGarrett D'Amore p->flags |= TERMP_HANG;
103495c635efSGarrett D'Amore } else {
103595c635efSGarrett D'Amore p->rmargin += term_len(p, 5);
103695c635efSGarrett D'Amore p->flags |= TERMP_HANG;
103795c635efSGarrett D'Amore }
103895c635efSGarrett D'Amore }
103995c635efSGarrett D'Amore
104095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
104195c635efSGarrett D'Amore if (NULL == n->child)
1042*698f87a4SGarrett D'Amore term_word(p, meta->name);
104395c635efSGarrett D'Amore return(1);
104495c635efSGarrett D'Amore }
104595c635efSGarrett D'Amore
104695c635efSGarrett D'Amore
104795c635efSGarrett D'Amore /* ARGSUSED */
104895c635efSGarrett D'Amore static void
termp_nm_post(DECL_ARGS)104995c635efSGarrett D'Amore termp_nm_post(DECL_ARGS)
105095c635efSGarrett D'Amore {
105195c635efSGarrett D'Amore
1052*698f87a4SGarrett D'Amore if (MDOC_BLOCK == n->type) {
1053*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
1054*698f87a4SGarrett D'Amore } else if (MDOC_HEAD == n->type && n->next->child) {
105595c635efSGarrett D'Amore term_flushln(p);
105695c635efSGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
1057*698f87a4SGarrett D'Amore p->trailspace = 0;
105895c635efSGarrett D'Amore } else if (MDOC_BODY == n->type && n->child)
105995c635efSGarrett D'Amore term_flushln(p);
106095c635efSGarrett D'Amore }
106195c635efSGarrett D'Amore
106295c635efSGarrett D'Amore
106395c635efSGarrett D'Amore /* ARGSUSED */
106495c635efSGarrett D'Amore static int
termp_fl_pre(DECL_ARGS)106595c635efSGarrett D'Amore termp_fl_pre(DECL_ARGS)
106695c635efSGarrett D'Amore {
106795c635efSGarrett D'Amore
106895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
106995c635efSGarrett D'Amore term_word(p, "\\-");
107095c635efSGarrett D'Amore
107195c635efSGarrett D'Amore if (n->child)
107295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
107395c635efSGarrett D'Amore else if (n->next && n->next->line == n->line)
107495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
107595c635efSGarrett D'Amore
107695c635efSGarrett D'Amore return(1);
107795c635efSGarrett D'Amore }
107895c635efSGarrett D'Amore
107995c635efSGarrett D'Amore
108095c635efSGarrett D'Amore /* ARGSUSED */
108195c635efSGarrett D'Amore static int
termp__a_pre(DECL_ARGS)108295c635efSGarrett D'Amore termp__a_pre(DECL_ARGS)
108395c635efSGarrett D'Amore {
108495c635efSGarrett D'Amore
108595c635efSGarrett D'Amore if (n->prev && MDOC__A == n->prev->tok)
108695c635efSGarrett D'Amore if (NULL == n->next || MDOC__A != n->next->tok)
108795c635efSGarrett D'Amore term_word(p, "and");
108895c635efSGarrett D'Amore
108995c635efSGarrett D'Amore return(1);
109095c635efSGarrett D'Amore }
109195c635efSGarrett D'Amore
109295c635efSGarrett D'Amore
109395c635efSGarrett D'Amore /* ARGSUSED */
109495c635efSGarrett D'Amore static int
termp_an_pre(DECL_ARGS)109595c635efSGarrett D'Amore termp_an_pre(DECL_ARGS)
109695c635efSGarrett D'Amore {
109795c635efSGarrett D'Amore
109895c635efSGarrett D'Amore if (NULL == n->child)
109995c635efSGarrett D'Amore return(1);
110095c635efSGarrett D'Amore
110195c635efSGarrett D'Amore /*
110295c635efSGarrett D'Amore * If not in the AUTHORS section, `An -split' will cause
110395c635efSGarrett D'Amore * newlines to occur before the author name. If in the AUTHORS
110495c635efSGarrett D'Amore * section, by default, the first `An' invocation is nosplit,
110595c635efSGarrett D'Amore * then all subsequent ones, regardless of whether interspersed
110695c635efSGarrett D'Amore * with other macros/text, are split. -split, in this case,
110795c635efSGarrett D'Amore * will override the condition of the implied first -nosplit.
110895c635efSGarrett D'Amore */
110995c635efSGarrett D'Amore
111095c635efSGarrett D'Amore if (n->sec == SEC_AUTHORS) {
111195c635efSGarrett D'Amore if ( ! (TERMP_ANPREC & p->flags)) {
111295c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags)
111395c635efSGarrett D'Amore term_newln(p);
111495c635efSGarrett D'Amore return(1);
111595c635efSGarrett D'Amore }
111695c635efSGarrett D'Amore if (TERMP_NOSPLIT & p->flags)
111795c635efSGarrett D'Amore return(1);
111895c635efSGarrett D'Amore term_newln(p);
111995c635efSGarrett D'Amore return(1);
112095c635efSGarrett D'Amore }
112195c635efSGarrett D'Amore
112295c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags)
112395c635efSGarrett D'Amore term_newln(p);
112495c635efSGarrett D'Amore
112595c635efSGarrett D'Amore return(1);
112695c635efSGarrett D'Amore }
112795c635efSGarrett D'Amore
112895c635efSGarrett D'Amore
112995c635efSGarrett D'Amore /* ARGSUSED */
113095c635efSGarrett D'Amore static void
termp_an_post(DECL_ARGS)113195c635efSGarrett D'Amore termp_an_post(DECL_ARGS)
113295c635efSGarrett D'Amore {
113395c635efSGarrett D'Amore
113495c635efSGarrett D'Amore if (n->child) {
113595c635efSGarrett D'Amore if (SEC_AUTHORS == n->sec)
113695c635efSGarrett D'Amore p->flags |= TERMP_ANPREC;
113795c635efSGarrett D'Amore return;
113895c635efSGarrett D'Amore }
113995c635efSGarrett D'Amore
114095c635efSGarrett D'Amore if (AUTH_split == n->norm->An.auth) {
114195c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPLIT;
114295c635efSGarrett D'Amore p->flags |= TERMP_SPLIT;
114395c635efSGarrett D'Amore } else if (AUTH_nosplit == n->norm->An.auth) {
114495c635efSGarrett D'Amore p->flags &= ~TERMP_SPLIT;
114595c635efSGarrett D'Amore p->flags |= TERMP_NOSPLIT;
114695c635efSGarrett D'Amore }
114795c635efSGarrett D'Amore
114895c635efSGarrett D'Amore }
114995c635efSGarrett D'Amore
115095c635efSGarrett D'Amore
115195c635efSGarrett D'Amore /* ARGSUSED */
115295c635efSGarrett D'Amore static int
termp_ns_pre(DECL_ARGS)115395c635efSGarrett D'Amore termp_ns_pre(DECL_ARGS)
115495c635efSGarrett D'Amore {
115595c635efSGarrett D'Amore
115695c635efSGarrett D'Amore if ( ! (MDOC_LINE & n->flags))
115795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
115895c635efSGarrett D'Amore return(1);
115995c635efSGarrett D'Amore }
116095c635efSGarrett D'Amore
116195c635efSGarrett D'Amore
116295c635efSGarrett D'Amore /* ARGSUSED */
116395c635efSGarrett D'Amore static int
termp_rs_pre(DECL_ARGS)116495c635efSGarrett D'Amore termp_rs_pre(DECL_ARGS)
116595c635efSGarrett D'Amore {
116695c635efSGarrett D'Amore
116795c635efSGarrett D'Amore if (SEC_SEE_ALSO != n->sec)
116895c635efSGarrett D'Amore return(1);
116995c635efSGarrett D'Amore if (MDOC_BLOCK == n->type && n->prev)
117095c635efSGarrett D'Amore term_vspace(p);
117195c635efSGarrett D'Amore return(1);
117295c635efSGarrett D'Amore }
117395c635efSGarrett D'Amore
117495c635efSGarrett D'Amore
117595c635efSGarrett D'Amore /* ARGSUSED */
117695c635efSGarrett D'Amore static int
termp_rv_pre(DECL_ARGS)117795c635efSGarrett D'Amore termp_rv_pre(DECL_ARGS)
117895c635efSGarrett D'Amore {
117995c635efSGarrett D'Amore int nchild;
118095c635efSGarrett D'Amore
118195c635efSGarrett D'Amore term_newln(p);
118295c635efSGarrett D'Amore term_word(p, "The");
118395c635efSGarrett D'Amore
118495c635efSGarrett D'Amore nchild = n->nchild;
118595c635efSGarrett D'Amore for (n = n->child; n; n = n->next) {
118695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
118795c635efSGarrett D'Amore term_word(p, n->string);
118895c635efSGarrett D'Amore term_fontpop(p);
118995c635efSGarrett D'Amore
119095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
119195c635efSGarrett D'Amore term_word(p, "()");
119295c635efSGarrett D'Amore
119395c635efSGarrett D'Amore if (nchild > 2 && n->next) {
119495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
119595c635efSGarrett D'Amore term_word(p, ",");
119695c635efSGarrett D'Amore }
119795c635efSGarrett D'Amore
119895c635efSGarrett D'Amore if (n->next && NULL == n->next->next)
119995c635efSGarrett D'Amore term_word(p, "and");
120095c635efSGarrett D'Amore }
120195c635efSGarrett D'Amore
120295c635efSGarrett D'Amore if (nchild > 1)
120395c635efSGarrett D'Amore term_word(p, "functions return");
120495c635efSGarrett D'Amore else
120595c635efSGarrett D'Amore term_word(p, "function returns");
120695c635efSGarrett D'Amore
120795c635efSGarrett D'Amore term_word(p, "the value 0 if successful; otherwise the value "
120895c635efSGarrett D'Amore "-1 is returned and the global variable");
120995c635efSGarrett D'Amore
121095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
121195c635efSGarrett D'Amore term_word(p, "errno");
121295c635efSGarrett D'Amore term_fontpop(p);
121395c635efSGarrett D'Amore
121495c635efSGarrett D'Amore term_word(p, "is set to indicate the error.");
121595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
121695c635efSGarrett D'Amore
121795c635efSGarrett D'Amore return(0);
121895c635efSGarrett D'Amore }
121995c635efSGarrett D'Amore
122095c635efSGarrett D'Amore
122195c635efSGarrett D'Amore /* ARGSUSED */
122295c635efSGarrett D'Amore static int
termp_ex_pre(DECL_ARGS)122395c635efSGarrett D'Amore termp_ex_pre(DECL_ARGS)
122495c635efSGarrett D'Amore {
122595c635efSGarrett D'Amore int nchild;
122695c635efSGarrett D'Amore
122795c635efSGarrett D'Amore term_newln(p);
122895c635efSGarrett D'Amore term_word(p, "The");
122995c635efSGarrett D'Amore
123095c635efSGarrett D'Amore nchild = n->nchild;
123195c635efSGarrett D'Amore for (n = n->child; n; n = n->next) {
123295c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
123395c635efSGarrett D'Amore term_word(p, n->string);
123495c635efSGarrett D'Amore term_fontpop(p);
123595c635efSGarrett D'Amore
123695c635efSGarrett D'Amore if (nchild > 2 && n->next) {
123795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
123895c635efSGarrett D'Amore term_word(p, ",");
123995c635efSGarrett D'Amore }
124095c635efSGarrett D'Amore
124195c635efSGarrett D'Amore if (n->next && NULL == n->next->next)
124295c635efSGarrett D'Amore term_word(p, "and");
124395c635efSGarrett D'Amore }
124495c635efSGarrett D'Amore
124595c635efSGarrett D'Amore if (nchild > 1)
124695c635efSGarrett D'Amore term_word(p, "utilities exit");
124795c635efSGarrett D'Amore else
124895c635efSGarrett D'Amore term_word(p, "utility exits");
124995c635efSGarrett D'Amore
125095c635efSGarrett D'Amore term_word(p, "0 on success, and >0 if an error occurs.");
125195c635efSGarrett D'Amore
125295c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
125395c635efSGarrett D'Amore return(0);
125495c635efSGarrett D'Amore }
125595c635efSGarrett D'Amore
125695c635efSGarrett D'Amore
125795c635efSGarrett D'Amore /* ARGSUSED */
125895c635efSGarrett D'Amore static int
termp_nd_pre(DECL_ARGS)125995c635efSGarrett D'Amore termp_nd_pre(DECL_ARGS)
126095c635efSGarrett D'Amore {
126195c635efSGarrett D'Amore
126295c635efSGarrett D'Amore if (MDOC_BODY != n->type)
126395c635efSGarrett D'Amore return(1);
126495c635efSGarrett D'Amore
126595c635efSGarrett D'Amore #if defined(__OpenBSD__) || defined(__linux__)
126695c635efSGarrett D'Amore term_word(p, "\\(en");
126795c635efSGarrett D'Amore #else
126895c635efSGarrett D'Amore term_word(p, "\\(em");
126995c635efSGarrett D'Amore #endif
127095c635efSGarrett D'Amore return(1);
127195c635efSGarrett D'Amore }
127295c635efSGarrett D'Amore
127395c635efSGarrett D'Amore
127495c635efSGarrett D'Amore /* ARGSUSED */
127595c635efSGarrett D'Amore static int
termp_bl_pre(DECL_ARGS)127695c635efSGarrett D'Amore termp_bl_pre(DECL_ARGS)
127795c635efSGarrett D'Amore {
127895c635efSGarrett D'Amore
127995c635efSGarrett D'Amore return(MDOC_HEAD != n->type);
128095c635efSGarrett D'Amore }
128195c635efSGarrett D'Amore
128295c635efSGarrett D'Amore
128395c635efSGarrett D'Amore /* ARGSUSED */
128495c635efSGarrett D'Amore static void
termp_bl_post(DECL_ARGS)128595c635efSGarrett D'Amore termp_bl_post(DECL_ARGS)
128695c635efSGarrett D'Amore {
128795c635efSGarrett D'Amore
128895c635efSGarrett D'Amore if (MDOC_BLOCK == n->type)
128995c635efSGarrett D'Amore term_newln(p);
129095c635efSGarrett D'Amore }
129195c635efSGarrett D'Amore
129295c635efSGarrett D'Amore /* ARGSUSED */
129395c635efSGarrett D'Amore static int
termp_xr_pre(DECL_ARGS)129495c635efSGarrett D'Amore termp_xr_pre(DECL_ARGS)
129595c635efSGarrett D'Amore {
129695c635efSGarrett D'Amore
129795c635efSGarrett D'Amore if (NULL == (n = n->child))
129895c635efSGarrett D'Amore return(0);
129995c635efSGarrett D'Amore
130095c635efSGarrett D'Amore assert(MDOC_TEXT == n->type);
130195c635efSGarrett D'Amore term_word(p, n->string);
130295c635efSGarrett D'Amore
130395c635efSGarrett D'Amore if (NULL == (n = n->next))
130495c635efSGarrett D'Amore return(0);
130595c635efSGarrett D'Amore
130695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
130795c635efSGarrett D'Amore term_word(p, "(");
130895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
130995c635efSGarrett D'Amore
131095c635efSGarrett D'Amore assert(MDOC_TEXT == n->type);
131195c635efSGarrett D'Amore term_word(p, n->string);
131295c635efSGarrett D'Amore
131395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
131495c635efSGarrett D'Amore term_word(p, ")");
131595c635efSGarrett D'Amore
131695c635efSGarrett D'Amore return(0);
131795c635efSGarrett D'Amore }
131895c635efSGarrett D'Amore
131995c635efSGarrett D'Amore /*
132095c635efSGarrett D'Amore * This decides how to assert whitespace before any of the SYNOPSIS set
132195c635efSGarrett D'Amore * of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain
132295c635efSGarrett D'Amore * macro combos).
132395c635efSGarrett D'Amore */
132495c635efSGarrett D'Amore static void
synopsis_pre(struct termp * p,const struct mdoc_node * n)132595c635efSGarrett D'Amore synopsis_pre(struct termp *p, const struct mdoc_node *n)
132695c635efSGarrett D'Amore {
132795c635efSGarrett D'Amore /*
132895c635efSGarrett D'Amore * Obviously, if we're not in a SYNOPSIS or no prior macros
132995c635efSGarrett D'Amore * exist, do nothing.
133095c635efSGarrett D'Amore */
133195c635efSGarrett D'Amore if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
133295c635efSGarrett D'Amore return;
133395c635efSGarrett D'Amore
133495c635efSGarrett D'Amore /*
133595c635efSGarrett D'Amore * If we're the second in a pair of like elements, emit our
133695c635efSGarrett D'Amore * newline and return. UNLESS we're `Fo', `Fn', `Fn', in which
133795c635efSGarrett D'Amore * case we soldier on.
133895c635efSGarrett D'Amore */
133995c635efSGarrett D'Amore if (n->prev->tok == n->tok &&
134095c635efSGarrett D'Amore MDOC_Ft != n->tok &&
134195c635efSGarrett D'Amore MDOC_Fo != n->tok &&
134295c635efSGarrett D'Amore MDOC_Fn != n->tok) {
134395c635efSGarrett D'Amore term_newln(p);
134495c635efSGarrett D'Amore return;
134595c635efSGarrett D'Amore }
134695c635efSGarrett D'Amore
134795c635efSGarrett D'Amore /*
134895c635efSGarrett D'Amore * If we're one of the SYNOPSIS set and non-like pair-wise after
134995c635efSGarrett D'Amore * another (or Fn/Fo, which we've let slip through) then assert
135095c635efSGarrett D'Amore * vertical space, else only newline and move on.
135195c635efSGarrett D'Amore */
135295c635efSGarrett D'Amore switch (n->prev->tok) {
135395c635efSGarrett D'Amore case (MDOC_Fd):
135495c635efSGarrett D'Amore /* FALLTHROUGH */
135595c635efSGarrett D'Amore case (MDOC_Fn):
135695c635efSGarrett D'Amore /* FALLTHROUGH */
135795c635efSGarrett D'Amore case (MDOC_Fo):
135895c635efSGarrett D'Amore /* FALLTHROUGH */
135995c635efSGarrett D'Amore case (MDOC_In):
136095c635efSGarrett D'Amore /* FALLTHROUGH */
136195c635efSGarrett D'Amore case (MDOC_Vt):
136295c635efSGarrett D'Amore term_vspace(p);
136395c635efSGarrett D'Amore break;
136495c635efSGarrett D'Amore case (MDOC_Ft):
136595c635efSGarrett D'Amore if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
136695c635efSGarrett D'Amore term_vspace(p);
136795c635efSGarrett D'Amore break;
136895c635efSGarrett D'Amore }
136995c635efSGarrett D'Amore /* FALLTHROUGH */
137095c635efSGarrett D'Amore default:
137195c635efSGarrett D'Amore term_newln(p);
137295c635efSGarrett D'Amore break;
137395c635efSGarrett D'Amore }
137495c635efSGarrett D'Amore }
137595c635efSGarrett D'Amore
137695c635efSGarrett D'Amore
137795c635efSGarrett D'Amore static int
termp_vt_pre(DECL_ARGS)137895c635efSGarrett D'Amore termp_vt_pre(DECL_ARGS)
137995c635efSGarrett D'Amore {
138095c635efSGarrett D'Amore
138195c635efSGarrett D'Amore if (MDOC_ELEM == n->type) {
138295c635efSGarrett D'Amore synopsis_pre(p, n);
1383*698f87a4SGarrett D'Amore return(termp_under_pre(p, pair, meta, n));
138495c635efSGarrett D'Amore } else if (MDOC_BLOCK == n->type) {
138595c635efSGarrett D'Amore synopsis_pre(p, n);
138695c635efSGarrett D'Amore return(1);
138795c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type)
138895c635efSGarrett D'Amore return(0);
138995c635efSGarrett D'Amore
1390*698f87a4SGarrett D'Amore return(termp_under_pre(p, pair, meta, n));
139195c635efSGarrett D'Amore }
139295c635efSGarrett D'Amore
139395c635efSGarrett D'Amore
139495c635efSGarrett D'Amore /* ARGSUSED */
139595c635efSGarrett D'Amore static int
termp_bold_pre(DECL_ARGS)139695c635efSGarrett D'Amore termp_bold_pre(DECL_ARGS)
139795c635efSGarrett D'Amore {
139895c635efSGarrett D'Amore
139995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
140095c635efSGarrett D'Amore return(1);
140195c635efSGarrett D'Amore }
140295c635efSGarrett D'Amore
140395c635efSGarrett D'Amore
140495c635efSGarrett D'Amore /* ARGSUSED */
140595c635efSGarrett D'Amore static int
termp_fd_pre(DECL_ARGS)140695c635efSGarrett D'Amore termp_fd_pre(DECL_ARGS)
140795c635efSGarrett D'Amore {
140895c635efSGarrett D'Amore
140995c635efSGarrett D'Amore synopsis_pre(p, n);
1410*698f87a4SGarrett D'Amore return(termp_bold_pre(p, pair, meta, n));
1411*698f87a4SGarrett D'Amore }
1412*698f87a4SGarrett D'Amore
1413*698f87a4SGarrett D'Amore
1414*698f87a4SGarrett D'Amore /* ARGSUSED */
1415*698f87a4SGarrett D'Amore static void
termp_fd_post(DECL_ARGS)1416*698f87a4SGarrett D'Amore termp_fd_post(DECL_ARGS)
1417*698f87a4SGarrett D'Amore {
1418*698f87a4SGarrett D'Amore
1419*698f87a4SGarrett D'Amore term_newln(p);
142095c635efSGarrett D'Amore }
142195c635efSGarrett D'Amore
142295c635efSGarrett D'Amore
142395c635efSGarrett D'Amore /* ARGSUSED */
142495c635efSGarrett D'Amore static int
termp_sh_pre(DECL_ARGS)142595c635efSGarrett D'Amore termp_sh_pre(DECL_ARGS)
142695c635efSGarrett D'Amore {
142795c635efSGarrett D'Amore
142895c635efSGarrett D'Amore /* No vspace between consecutive `Sh' calls. */
142995c635efSGarrett D'Amore
143095c635efSGarrett D'Amore switch (n->type) {
143195c635efSGarrett D'Amore case (MDOC_BLOCK):
143295c635efSGarrett D'Amore if (n->prev && MDOC_Sh == n->prev->tok)
143395c635efSGarrett D'Amore if (NULL == n->prev->body->child)
143495c635efSGarrett D'Amore break;
143595c635efSGarrett D'Amore term_vspace(p);
143695c635efSGarrett D'Amore break;
143795c635efSGarrett D'Amore case (MDOC_HEAD):
143895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
143995c635efSGarrett D'Amore break;
144095c635efSGarrett D'Amore case (MDOC_BODY):
144195c635efSGarrett D'Amore p->offset = term_len(p, p->defindent);
1442*698f87a4SGarrett D'Amore if (SEC_AUTHORS == n->sec)
1443*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT);
144495c635efSGarrett D'Amore break;
144595c635efSGarrett D'Amore default:
144695c635efSGarrett D'Amore break;
144795c635efSGarrett D'Amore }
144895c635efSGarrett D'Amore return(1);
144995c635efSGarrett D'Amore }
145095c635efSGarrett D'Amore
145195c635efSGarrett D'Amore
145295c635efSGarrett D'Amore /* ARGSUSED */
145395c635efSGarrett D'Amore static void
termp_sh_post(DECL_ARGS)145495c635efSGarrett D'Amore termp_sh_post(DECL_ARGS)
145595c635efSGarrett D'Amore {
145695c635efSGarrett D'Amore
145795c635efSGarrett D'Amore switch (n->type) {
145895c635efSGarrett D'Amore case (MDOC_HEAD):
145995c635efSGarrett D'Amore term_newln(p);
146095c635efSGarrett D'Amore break;
146195c635efSGarrett D'Amore case (MDOC_BODY):
146295c635efSGarrett D'Amore term_newln(p);
146395c635efSGarrett D'Amore p->offset = 0;
146495c635efSGarrett D'Amore break;
146595c635efSGarrett D'Amore default:
146695c635efSGarrett D'Amore break;
146795c635efSGarrett D'Amore }
146895c635efSGarrett D'Amore }
146995c635efSGarrett D'Amore
147095c635efSGarrett D'Amore
147195c635efSGarrett D'Amore /* ARGSUSED */
147295c635efSGarrett D'Amore static int
termp_bt_pre(DECL_ARGS)147395c635efSGarrett D'Amore termp_bt_pre(DECL_ARGS)
147495c635efSGarrett D'Amore {
147595c635efSGarrett D'Amore
147695c635efSGarrett D'Amore term_word(p, "is currently in beta test.");
147795c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
147895c635efSGarrett D'Amore return(0);
147995c635efSGarrett D'Amore }
148095c635efSGarrett D'Amore
148195c635efSGarrett D'Amore
148295c635efSGarrett D'Amore /* ARGSUSED */
148395c635efSGarrett D'Amore static void
termp_lb_post(DECL_ARGS)148495c635efSGarrett D'Amore termp_lb_post(DECL_ARGS)
148595c635efSGarrett D'Amore {
148695c635efSGarrett D'Amore
148795c635efSGarrett D'Amore if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags)
148895c635efSGarrett D'Amore term_newln(p);
148995c635efSGarrett D'Amore }
149095c635efSGarrett D'Amore
149195c635efSGarrett D'Amore
149295c635efSGarrett D'Amore /* ARGSUSED */
149395c635efSGarrett D'Amore static int
termp_ud_pre(DECL_ARGS)149495c635efSGarrett D'Amore termp_ud_pre(DECL_ARGS)
149595c635efSGarrett D'Amore {
149695c635efSGarrett D'Amore
149795c635efSGarrett D'Amore term_word(p, "currently under development.");
149895c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
149995c635efSGarrett D'Amore return(0);
150095c635efSGarrett D'Amore }
150195c635efSGarrett D'Amore
150295c635efSGarrett D'Amore
150395c635efSGarrett D'Amore /* ARGSUSED */
150495c635efSGarrett D'Amore static int
termp_d1_pre(DECL_ARGS)150595c635efSGarrett D'Amore termp_d1_pre(DECL_ARGS)
150695c635efSGarrett D'Amore {
150795c635efSGarrett D'Amore
150895c635efSGarrett D'Amore if (MDOC_BLOCK != n->type)
150995c635efSGarrett D'Amore return(1);
151095c635efSGarrett D'Amore term_newln(p);
151195c635efSGarrett D'Amore p->offset += term_len(p, p->defindent + 1);
151295c635efSGarrett D'Amore return(1);
151395c635efSGarrett D'Amore }
151495c635efSGarrett D'Amore
151595c635efSGarrett D'Amore
151695c635efSGarrett D'Amore /* ARGSUSED */
151795c635efSGarrett D'Amore static int
termp_ft_pre(DECL_ARGS)151895c635efSGarrett D'Amore termp_ft_pre(DECL_ARGS)
151995c635efSGarrett D'Amore {
152095c635efSGarrett D'Amore
152195c635efSGarrett D'Amore /* NB: MDOC_LINE does not effect this! */
152295c635efSGarrett D'Amore synopsis_pre(p, n);
152395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
152495c635efSGarrett D'Amore return(1);
152595c635efSGarrett D'Amore }
152695c635efSGarrett D'Amore
152795c635efSGarrett D'Amore
152895c635efSGarrett D'Amore /* ARGSUSED */
152995c635efSGarrett D'Amore static int
termp_fn_pre(DECL_ARGS)153095c635efSGarrett D'Amore termp_fn_pre(DECL_ARGS)
153195c635efSGarrett D'Amore {
1532*698f87a4SGarrett D'Amore size_t rmargin = 0;
153395c635efSGarrett D'Amore int pretty;
153495c635efSGarrett D'Amore
153595c635efSGarrett D'Amore pretty = MDOC_SYNPRETTY & n->flags;
153695c635efSGarrett D'Amore
153795c635efSGarrett D'Amore synopsis_pre(p, n);
153895c635efSGarrett D'Amore
153995c635efSGarrett D'Amore if (NULL == (n = n->child))
154095c635efSGarrett D'Amore return(0);
154195c635efSGarrett D'Amore
1542*698f87a4SGarrett D'Amore if (pretty) {
1543*698f87a4SGarrett D'Amore rmargin = p->rmargin;
1544*698f87a4SGarrett D'Amore p->rmargin = p->offset + term_len(p, 4);
1545*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG;
1546*698f87a4SGarrett D'Amore }
1547*698f87a4SGarrett D'Amore
154895c635efSGarrett D'Amore assert(MDOC_TEXT == n->type);
154995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
155095c635efSGarrett D'Amore term_word(p, n->string);
155195c635efSGarrett D'Amore term_fontpop(p);
155295c635efSGarrett D'Amore
1553*698f87a4SGarrett D'Amore if (pretty) {
1554*698f87a4SGarrett D'Amore term_flushln(p);
1555*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
1556*698f87a4SGarrett D'Amore p->offset = p->rmargin;
1557*698f87a4SGarrett D'Amore p->rmargin = rmargin;
1558*698f87a4SGarrett D'Amore }
1559*698f87a4SGarrett D'Amore
156095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
156195c635efSGarrett D'Amore term_word(p, "(");
156295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
156395c635efSGarrett D'Amore
156495c635efSGarrett D'Amore for (n = n->next; n; n = n->next) {
156595c635efSGarrett D'Amore assert(MDOC_TEXT == n->type);
156695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
1567*698f87a4SGarrett D'Amore if (pretty)
1568*698f87a4SGarrett D'Amore p->flags |= TERMP_NBRWORD;
156995c635efSGarrett D'Amore term_word(p, n->string);
157095c635efSGarrett D'Amore term_fontpop(p);
157195c635efSGarrett D'Amore
157295c635efSGarrett D'Amore if (n->next) {
157395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
157495c635efSGarrett D'Amore term_word(p, ",");
157595c635efSGarrett D'Amore }
157695c635efSGarrett D'Amore }
157795c635efSGarrett D'Amore
157895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
157995c635efSGarrett D'Amore term_word(p, ")");
158095c635efSGarrett D'Amore
158195c635efSGarrett D'Amore if (pretty) {
158295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
158395c635efSGarrett D'Amore term_word(p, ";");
1584*698f87a4SGarrett D'Amore term_flushln(p);
158595c635efSGarrett D'Amore }
158695c635efSGarrett D'Amore
158795c635efSGarrett D'Amore return(0);
158895c635efSGarrett D'Amore }
158995c635efSGarrett D'Amore
159095c635efSGarrett D'Amore
159195c635efSGarrett D'Amore /* ARGSUSED */
159295c635efSGarrett D'Amore static int
termp_fa_pre(DECL_ARGS)159395c635efSGarrett D'Amore termp_fa_pre(DECL_ARGS)
159495c635efSGarrett D'Amore {
159595c635efSGarrett D'Amore const struct mdoc_node *nn;
159695c635efSGarrett D'Amore
159795c635efSGarrett D'Amore if (n->parent->tok != MDOC_Fo) {
159895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
159995c635efSGarrett D'Amore return(1);
160095c635efSGarrett D'Amore }
160195c635efSGarrett D'Amore
160295c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) {
160395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
1604*698f87a4SGarrett D'Amore p->flags |= TERMP_NBRWORD;
160595c635efSGarrett D'Amore term_word(p, nn->string);
160695c635efSGarrett D'Amore term_fontpop(p);
160795c635efSGarrett D'Amore
1608*698f87a4SGarrett D'Amore if (nn->next || (n->next && n->next->tok == MDOC_Fa)) {
160995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
161095c635efSGarrett D'Amore term_word(p, ",");
161195c635efSGarrett D'Amore }
161295c635efSGarrett D'Amore }
161395c635efSGarrett D'Amore
161495c635efSGarrett D'Amore return(0);
161595c635efSGarrett D'Amore }
161695c635efSGarrett D'Amore
161795c635efSGarrett D'Amore
161895c635efSGarrett D'Amore /* ARGSUSED */
161995c635efSGarrett D'Amore static int
termp_bd_pre(DECL_ARGS)162095c635efSGarrett D'Amore termp_bd_pre(DECL_ARGS)
162195c635efSGarrett D'Amore {
162295c635efSGarrett D'Amore size_t tabwidth, rm, rmax;
1623*698f87a4SGarrett D'Amore struct mdoc_node *nn;
162495c635efSGarrett D'Amore
162595c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) {
162695c635efSGarrett D'Amore print_bvspace(p, n, n);
162795c635efSGarrett D'Amore return(1);
162895c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type)
162995c635efSGarrett D'Amore return(0);
163095c635efSGarrett D'Amore
163195c635efSGarrett D'Amore if (n->norm->Bd.offs)
163295c635efSGarrett D'Amore p->offset += a2offs(p, n->norm->Bd.offs);
163395c635efSGarrett D'Amore
163495c635efSGarrett D'Amore /*
163595c635efSGarrett D'Amore * If -ragged or -filled are specified, the block does nothing
163695c635efSGarrett D'Amore * but change the indentation. If -unfilled or -literal are
163795c635efSGarrett D'Amore * specified, text is printed exactly as entered in the display:
163895c635efSGarrett D'Amore * for macro lines, a newline is appended to the line. Blank
163995c635efSGarrett D'Amore * lines are allowed.
164095c635efSGarrett D'Amore */
164195c635efSGarrett D'Amore
164295c635efSGarrett D'Amore if (DISP_literal != n->norm->Bd.type &&
164395c635efSGarrett D'Amore DISP_unfilled != n->norm->Bd.type)
164495c635efSGarrett D'Amore return(1);
164595c635efSGarrett D'Amore
164695c635efSGarrett D'Amore tabwidth = p->tabwidth;
164795c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type)
164895c635efSGarrett D'Amore p->tabwidth = term_len(p, 8);
164995c635efSGarrett D'Amore
165095c635efSGarrett D'Amore rm = p->rmargin;
165195c635efSGarrett D'Amore rmax = p->maxrmargin;
165295c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
165395c635efSGarrett D'Amore
165495c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) {
1655*698f87a4SGarrett D'Amore print_mdoc_node(p, pair, meta, nn);
165695c635efSGarrett D'Amore /*
165795c635efSGarrett D'Amore * If the printed node flushes its own line, then we
165895c635efSGarrett D'Amore * needn't do it here as well. This is hacky, but the
165995c635efSGarrett D'Amore * notion of selective eoln whitespace is pretty dumb
166095c635efSGarrett D'Amore * anyway, so don't sweat it.
166195c635efSGarrett D'Amore */
166295c635efSGarrett D'Amore switch (nn->tok) {
166395c635efSGarrett D'Amore case (MDOC_Sm):
166495c635efSGarrett D'Amore /* FALLTHROUGH */
166595c635efSGarrett D'Amore case (MDOC_br):
166695c635efSGarrett D'Amore /* FALLTHROUGH */
166795c635efSGarrett D'Amore case (MDOC_sp):
166895c635efSGarrett D'Amore /* FALLTHROUGH */
166995c635efSGarrett D'Amore case (MDOC_Bl):
167095c635efSGarrett D'Amore /* FALLTHROUGH */
167195c635efSGarrett D'Amore case (MDOC_D1):
167295c635efSGarrett D'Amore /* FALLTHROUGH */
167395c635efSGarrett D'Amore case (MDOC_Dl):
167495c635efSGarrett D'Amore /* FALLTHROUGH */
167595c635efSGarrett D'Amore case (MDOC_Lp):
167695c635efSGarrett D'Amore /* FALLTHROUGH */
167795c635efSGarrett D'Amore case (MDOC_Pp):
167895c635efSGarrett D'Amore continue;
167995c635efSGarrett D'Amore default:
168095c635efSGarrett D'Amore break;
168195c635efSGarrett D'Amore }
168295c635efSGarrett D'Amore if (nn->next && nn->next->line == nn->line)
168395c635efSGarrett D'Amore continue;
168495c635efSGarrett D'Amore term_flushln(p);
168595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
168695c635efSGarrett D'Amore }
168795c635efSGarrett D'Amore
168895c635efSGarrett D'Amore p->tabwidth = tabwidth;
168995c635efSGarrett D'Amore p->rmargin = rm;
169095c635efSGarrett D'Amore p->maxrmargin = rmax;
169195c635efSGarrett D'Amore return(0);
169295c635efSGarrett D'Amore }
169395c635efSGarrett D'Amore
169495c635efSGarrett D'Amore
169595c635efSGarrett D'Amore /* ARGSUSED */
169695c635efSGarrett D'Amore static void
termp_bd_post(DECL_ARGS)169795c635efSGarrett D'Amore termp_bd_post(DECL_ARGS)
169895c635efSGarrett D'Amore {
169995c635efSGarrett D'Amore size_t rm, rmax;
170095c635efSGarrett D'Amore
170195c635efSGarrett D'Amore if (MDOC_BODY != n->type)
170295c635efSGarrett D'Amore return;
170395c635efSGarrett D'Amore
170495c635efSGarrett D'Amore rm = p->rmargin;
170595c635efSGarrett D'Amore rmax = p->maxrmargin;
170695c635efSGarrett D'Amore
170795c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type ||
170895c635efSGarrett D'Amore DISP_unfilled == n->norm->Bd.type)
170995c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
171095c635efSGarrett D'Amore
171195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
171295c635efSGarrett D'Amore term_newln(p);
171395c635efSGarrett D'Amore
171495c635efSGarrett D'Amore p->rmargin = rm;
171595c635efSGarrett D'Amore p->maxrmargin = rmax;
171695c635efSGarrett D'Amore }
171795c635efSGarrett D'Amore
171895c635efSGarrett D'Amore
171995c635efSGarrett D'Amore /* ARGSUSED */
172095c635efSGarrett D'Amore static int
termp_bx_pre(DECL_ARGS)172195c635efSGarrett D'Amore termp_bx_pre(DECL_ARGS)
172295c635efSGarrett D'Amore {
172395c635efSGarrett D'Amore
172495c635efSGarrett D'Amore if (NULL != (n = n->child)) {
172595c635efSGarrett D'Amore term_word(p, n->string);
172695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
172795c635efSGarrett D'Amore term_word(p, "BSD");
172895c635efSGarrett D'Amore } else {
172995c635efSGarrett D'Amore term_word(p, "BSD");
173095c635efSGarrett D'Amore return(0);
173195c635efSGarrett D'Amore }
173295c635efSGarrett D'Amore
173395c635efSGarrett D'Amore if (NULL != (n = n->next)) {
173495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
173595c635efSGarrett D'Amore term_word(p, "-");
173695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
173795c635efSGarrett D'Amore term_word(p, n->string);
173895c635efSGarrett D'Amore }
173995c635efSGarrett D'Amore
174095c635efSGarrett D'Amore return(0);
174195c635efSGarrett D'Amore }
174295c635efSGarrett D'Amore
174395c635efSGarrett D'Amore
174495c635efSGarrett D'Amore /* ARGSUSED */
174595c635efSGarrett D'Amore static int
termp_xx_pre(DECL_ARGS)174695c635efSGarrett D'Amore termp_xx_pre(DECL_ARGS)
174795c635efSGarrett D'Amore {
174895c635efSGarrett D'Amore const char *pp;
174995c635efSGarrett D'Amore int flags;
175095c635efSGarrett D'Amore
175195c635efSGarrett D'Amore pp = NULL;
175295c635efSGarrett D'Amore switch (n->tok) {
175395c635efSGarrett D'Amore case (MDOC_Bsx):
175495c635efSGarrett D'Amore pp = "BSD/OS";
175595c635efSGarrett D'Amore break;
175695c635efSGarrett D'Amore case (MDOC_Dx):
175795c635efSGarrett D'Amore pp = "DragonFly";
175895c635efSGarrett D'Amore break;
175995c635efSGarrett D'Amore case (MDOC_Fx):
176095c635efSGarrett D'Amore pp = "FreeBSD";
176195c635efSGarrett D'Amore break;
176295c635efSGarrett D'Amore case (MDOC_Nx):
176395c635efSGarrett D'Amore pp = "NetBSD";
176495c635efSGarrett D'Amore break;
176595c635efSGarrett D'Amore case (MDOC_Ox):
176695c635efSGarrett D'Amore pp = "OpenBSD";
176795c635efSGarrett D'Amore break;
176895c635efSGarrett D'Amore case (MDOC_Ux):
176995c635efSGarrett D'Amore pp = "UNIX";
177095c635efSGarrett D'Amore break;
177195c635efSGarrett D'Amore default:
1772*698f87a4SGarrett D'Amore abort();
1773*698f87a4SGarrett D'Amore /* NOTREACHED */
177495c635efSGarrett D'Amore }
177595c635efSGarrett D'Amore
177695c635efSGarrett D'Amore term_word(p, pp);
177795c635efSGarrett D'Amore if (n->child) {
177895c635efSGarrett D'Amore flags = p->flags;
177995c635efSGarrett D'Amore p->flags |= TERMP_KEEP;
178095c635efSGarrett D'Amore term_word(p, n->child->string);
178195c635efSGarrett D'Amore p->flags = flags;
178295c635efSGarrett D'Amore }
178395c635efSGarrett D'Amore return(0);
178495c635efSGarrett D'Amore }
178595c635efSGarrett D'Amore
178695c635efSGarrett D'Amore
178795c635efSGarrett D'Amore /* ARGSUSED */
178895c635efSGarrett D'Amore static void
termp_pf_post(DECL_ARGS)178995c635efSGarrett D'Amore termp_pf_post(DECL_ARGS)
179095c635efSGarrett D'Amore {
179195c635efSGarrett D'Amore
179295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
179395c635efSGarrett D'Amore }
179495c635efSGarrett D'Amore
179595c635efSGarrett D'Amore
179695c635efSGarrett D'Amore /* ARGSUSED */
179795c635efSGarrett D'Amore static int
termp_ss_pre(DECL_ARGS)179895c635efSGarrett D'Amore termp_ss_pre(DECL_ARGS)
179995c635efSGarrett D'Amore {
180095c635efSGarrett D'Amore
180195c635efSGarrett D'Amore switch (n->type) {
180295c635efSGarrett D'Amore case (MDOC_BLOCK):
180395c635efSGarrett D'Amore term_newln(p);
180495c635efSGarrett D'Amore if (n->prev)
180595c635efSGarrett D'Amore term_vspace(p);
180695c635efSGarrett D'Amore break;
180795c635efSGarrett D'Amore case (MDOC_HEAD):
180895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
180995c635efSGarrett D'Amore p->offset = term_len(p, (p->defindent+1)/2);
181095c635efSGarrett D'Amore break;
181195c635efSGarrett D'Amore default:
181295c635efSGarrett D'Amore break;
181395c635efSGarrett D'Amore }
181495c635efSGarrett D'Amore
181595c635efSGarrett D'Amore return(1);
181695c635efSGarrett D'Amore }
181795c635efSGarrett D'Amore
181895c635efSGarrett D'Amore
181995c635efSGarrett D'Amore /* ARGSUSED */
182095c635efSGarrett D'Amore static void
termp_ss_post(DECL_ARGS)182195c635efSGarrett D'Amore termp_ss_post(DECL_ARGS)
182295c635efSGarrett D'Amore {
182395c635efSGarrett D'Amore
182495c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
182595c635efSGarrett D'Amore term_newln(p);
182695c635efSGarrett D'Amore }
182795c635efSGarrett D'Amore
182895c635efSGarrett D'Amore
182995c635efSGarrett D'Amore /* ARGSUSED */
183095c635efSGarrett D'Amore static int
termp_cd_pre(DECL_ARGS)183195c635efSGarrett D'Amore termp_cd_pre(DECL_ARGS)
183295c635efSGarrett D'Amore {
183395c635efSGarrett D'Amore
183495c635efSGarrett D'Amore synopsis_pre(p, n);
183595c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
183695c635efSGarrett D'Amore return(1);
183795c635efSGarrett D'Amore }
183895c635efSGarrett D'Amore
183995c635efSGarrett D'Amore
184095c635efSGarrett D'Amore /* ARGSUSED */
184195c635efSGarrett D'Amore static int
termp_in_pre(DECL_ARGS)184295c635efSGarrett D'Amore termp_in_pre(DECL_ARGS)
184395c635efSGarrett D'Amore {
184495c635efSGarrett D'Amore
184595c635efSGarrett D'Amore synopsis_pre(p, n);
184695c635efSGarrett D'Amore
184795c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) {
184895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
184995c635efSGarrett D'Amore term_word(p, "#include");
185095c635efSGarrett D'Amore term_word(p, "<");
185195c635efSGarrett D'Amore } else {
185295c635efSGarrett D'Amore term_word(p, "<");
185395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
185495c635efSGarrett D'Amore }
185595c635efSGarrett D'Amore
185695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
185795c635efSGarrett D'Amore return(1);
185895c635efSGarrett D'Amore }
185995c635efSGarrett D'Amore
186095c635efSGarrett D'Amore
186195c635efSGarrett D'Amore /* ARGSUSED */
186295c635efSGarrett D'Amore static void
termp_in_post(DECL_ARGS)186395c635efSGarrett D'Amore termp_in_post(DECL_ARGS)
186495c635efSGarrett D'Amore {
186595c635efSGarrett D'Amore
186695c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags)
186795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
186895c635efSGarrett D'Amore
186995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
187095c635efSGarrett D'Amore term_word(p, ">");
187195c635efSGarrett D'Amore
187295c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags)
187395c635efSGarrett D'Amore term_fontpop(p);
187495c635efSGarrett D'Amore }
187595c635efSGarrett D'Amore
187695c635efSGarrett D'Amore
187795c635efSGarrett D'Amore /* ARGSUSED */
187895c635efSGarrett D'Amore static int
termp_sp_pre(DECL_ARGS)187995c635efSGarrett D'Amore termp_sp_pre(DECL_ARGS)
188095c635efSGarrett D'Amore {
188195c635efSGarrett D'Amore size_t i, len;
188295c635efSGarrett D'Amore
188395c635efSGarrett D'Amore switch (n->tok) {
188495c635efSGarrett D'Amore case (MDOC_sp):
188595c635efSGarrett D'Amore len = n->child ? a2height(p, n->child->string) : 1;
188695c635efSGarrett D'Amore break;
188795c635efSGarrett D'Amore case (MDOC_br):
188895c635efSGarrett D'Amore len = 0;
188995c635efSGarrett D'Amore break;
189095c635efSGarrett D'Amore default:
189195c635efSGarrett D'Amore len = 1;
189295c635efSGarrett D'Amore break;
189395c635efSGarrett D'Amore }
189495c635efSGarrett D'Amore
189595c635efSGarrett D'Amore if (0 == len)
189695c635efSGarrett D'Amore term_newln(p);
189795c635efSGarrett D'Amore for (i = 0; i < len; i++)
189895c635efSGarrett D'Amore term_vspace(p);
189995c635efSGarrett D'Amore
190095c635efSGarrett D'Amore return(0);
190195c635efSGarrett D'Amore }
190295c635efSGarrett D'Amore
190395c635efSGarrett D'Amore
190495c635efSGarrett D'Amore /* ARGSUSED */
190595c635efSGarrett D'Amore static int
termp_quote_pre(DECL_ARGS)190695c635efSGarrett D'Amore termp_quote_pre(DECL_ARGS)
190795c635efSGarrett D'Amore {
190895c635efSGarrett D'Amore
190995c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type)
191095c635efSGarrett D'Amore return(1);
191195c635efSGarrett D'Amore
191295c635efSGarrett D'Amore switch (n->tok) {
191395c635efSGarrett D'Amore case (MDOC_Ao):
191495c635efSGarrett D'Amore /* FALLTHROUGH */
191595c635efSGarrett D'Amore case (MDOC_Aq):
191695c635efSGarrett D'Amore term_word(p, "<");
191795c635efSGarrett D'Amore break;
191895c635efSGarrett D'Amore case (MDOC_Bro):
191995c635efSGarrett D'Amore /* FALLTHROUGH */
192095c635efSGarrett D'Amore case (MDOC_Brq):
192195c635efSGarrett D'Amore term_word(p, "{");
192295c635efSGarrett D'Amore break;
192395c635efSGarrett D'Amore case (MDOC_Oo):
192495c635efSGarrett D'Amore /* FALLTHROUGH */
192595c635efSGarrett D'Amore case (MDOC_Op):
192695c635efSGarrett D'Amore /* FALLTHROUGH */
192795c635efSGarrett D'Amore case (MDOC_Bo):
192895c635efSGarrett D'Amore /* FALLTHROUGH */
192995c635efSGarrett D'Amore case (MDOC_Bq):
193095c635efSGarrett D'Amore term_word(p, "[");
193195c635efSGarrett D'Amore break;
193295c635efSGarrett D'Amore case (MDOC_Do):
193395c635efSGarrett D'Amore /* FALLTHROUGH */
193495c635efSGarrett D'Amore case (MDOC_Dq):
1935*698f87a4SGarrett D'Amore term_word(p, "\\(lq");
193695c635efSGarrett D'Amore break;
193795c635efSGarrett D'Amore case (MDOC_Eo):
193895c635efSGarrett D'Amore break;
193995c635efSGarrett D'Amore case (MDOC_Po):
194095c635efSGarrett D'Amore /* FALLTHROUGH */
194195c635efSGarrett D'Amore case (MDOC_Pq):
194295c635efSGarrett D'Amore term_word(p, "(");
194395c635efSGarrett D'Amore break;
194495c635efSGarrett D'Amore case (MDOC__T):
194595c635efSGarrett D'Amore /* FALLTHROUGH */
194695c635efSGarrett D'Amore case (MDOC_Qo):
194795c635efSGarrett D'Amore /* FALLTHROUGH */
194895c635efSGarrett D'Amore case (MDOC_Qq):
194995c635efSGarrett D'Amore term_word(p, "\"");
195095c635efSGarrett D'Amore break;
195195c635efSGarrett D'Amore case (MDOC_Ql):
195295c635efSGarrett D'Amore /* FALLTHROUGH */
195395c635efSGarrett D'Amore case (MDOC_So):
195495c635efSGarrett D'Amore /* FALLTHROUGH */
195595c635efSGarrett D'Amore case (MDOC_Sq):
1956*698f87a4SGarrett D'Amore term_word(p, "\\(oq");
195795c635efSGarrett D'Amore break;
195895c635efSGarrett D'Amore default:
195995c635efSGarrett D'Amore abort();
196095c635efSGarrett D'Amore /* NOTREACHED */
196195c635efSGarrett D'Amore }
196295c635efSGarrett D'Amore
196395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
196495c635efSGarrett D'Amore return(1);
196595c635efSGarrett D'Amore }
196695c635efSGarrett D'Amore
196795c635efSGarrett D'Amore
196895c635efSGarrett D'Amore /* ARGSUSED */
196995c635efSGarrett D'Amore static void
termp_quote_post(DECL_ARGS)197095c635efSGarrett D'Amore termp_quote_post(DECL_ARGS)
197195c635efSGarrett D'Amore {
197295c635efSGarrett D'Amore
197395c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type)
197495c635efSGarrett D'Amore return;
197595c635efSGarrett D'Amore
197695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
197795c635efSGarrett D'Amore
197895c635efSGarrett D'Amore switch (n->tok) {
197995c635efSGarrett D'Amore case (MDOC_Ao):
198095c635efSGarrett D'Amore /* FALLTHROUGH */
198195c635efSGarrett D'Amore case (MDOC_Aq):
198295c635efSGarrett D'Amore term_word(p, ">");
198395c635efSGarrett D'Amore break;
198495c635efSGarrett D'Amore case (MDOC_Bro):
198595c635efSGarrett D'Amore /* FALLTHROUGH */
198695c635efSGarrett D'Amore case (MDOC_Brq):
198795c635efSGarrett D'Amore term_word(p, "}");
198895c635efSGarrett D'Amore break;
198995c635efSGarrett D'Amore case (MDOC_Oo):
199095c635efSGarrett D'Amore /* FALLTHROUGH */
199195c635efSGarrett D'Amore case (MDOC_Op):
199295c635efSGarrett D'Amore /* FALLTHROUGH */
199395c635efSGarrett D'Amore case (MDOC_Bo):
199495c635efSGarrett D'Amore /* FALLTHROUGH */
199595c635efSGarrett D'Amore case (MDOC_Bq):
199695c635efSGarrett D'Amore term_word(p, "]");
199795c635efSGarrett D'Amore break;
199895c635efSGarrett D'Amore case (MDOC_Do):
199995c635efSGarrett D'Amore /* FALLTHROUGH */
200095c635efSGarrett D'Amore case (MDOC_Dq):
2001*698f87a4SGarrett D'Amore term_word(p, "\\(rq");
200295c635efSGarrett D'Amore break;
200395c635efSGarrett D'Amore case (MDOC_Eo):
200495c635efSGarrett D'Amore break;
200595c635efSGarrett D'Amore case (MDOC_Po):
200695c635efSGarrett D'Amore /* FALLTHROUGH */
200795c635efSGarrett D'Amore case (MDOC_Pq):
200895c635efSGarrett D'Amore term_word(p, ")");
200995c635efSGarrett D'Amore break;
201095c635efSGarrett D'Amore case (MDOC__T):
201195c635efSGarrett D'Amore /* FALLTHROUGH */
201295c635efSGarrett D'Amore case (MDOC_Qo):
201395c635efSGarrett D'Amore /* FALLTHROUGH */
201495c635efSGarrett D'Amore case (MDOC_Qq):
201595c635efSGarrett D'Amore term_word(p, "\"");
201695c635efSGarrett D'Amore break;
201795c635efSGarrett D'Amore case (MDOC_Ql):
201895c635efSGarrett D'Amore /* FALLTHROUGH */
201995c635efSGarrett D'Amore case (MDOC_So):
202095c635efSGarrett D'Amore /* FALLTHROUGH */
202195c635efSGarrett D'Amore case (MDOC_Sq):
2022*698f87a4SGarrett D'Amore term_word(p, "\\(cq");
202395c635efSGarrett D'Amore break;
202495c635efSGarrett D'Amore default:
202595c635efSGarrett D'Amore abort();
202695c635efSGarrett D'Amore /* NOTREACHED */
202795c635efSGarrett D'Amore }
202895c635efSGarrett D'Amore }
202995c635efSGarrett D'Amore
203095c635efSGarrett D'Amore
203195c635efSGarrett D'Amore /* ARGSUSED */
203295c635efSGarrett D'Amore static int
termp_fo_pre(DECL_ARGS)203395c635efSGarrett D'Amore termp_fo_pre(DECL_ARGS)
203495c635efSGarrett D'Amore {
2035*698f87a4SGarrett D'Amore size_t rmargin = 0;
2036*698f87a4SGarrett D'Amore int pretty;
2037*698f87a4SGarrett D'Amore
2038*698f87a4SGarrett D'Amore pretty = MDOC_SYNPRETTY & n->flags;
203995c635efSGarrett D'Amore
204095c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) {
204195c635efSGarrett D'Amore synopsis_pre(p, n);
204295c635efSGarrett D'Amore return(1);
204395c635efSGarrett D'Amore } else if (MDOC_BODY == n->type) {
2044*698f87a4SGarrett D'Amore if (pretty) {
2045*698f87a4SGarrett D'Amore rmargin = p->rmargin;
2046*698f87a4SGarrett D'Amore p->rmargin = p->offset + term_len(p, 4);
2047*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG;
2048*698f87a4SGarrett D'Amore }
204995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
205095c635efSGarrett D'Amore term_word(p, "(");
205195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
2052*698f87a4SGarrett D'Amore if (pretty) {
2053*698f87a4SGarrett D'Amore term_flushln(p);
2054*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
2055*698f87a4SGarrett D'Amore p->offset = p->rmargin;
2056*698f87a4SGarrett D'Amore p->rmargin = rmargin;
2057*698f87a4SGarrett D'Amore }
205895c635efSGarrett D'Amore return(1);
205995c635efSGarrett D'Amore }
206095c635efSGarrett D'Amore
206195c635efSGarrett D'Amore if (NULL == n->child)
206295c635efSGarrett D'Amore return(0);
206395c635efSGarrett D'Amore
206495c635efSGarrett D'Amore /* XXX: we drop non-initial arguments as per groff. */
206595c635efSGarrett D'Amore
206695c635efSGarrett D'Amore assert(n->child->string);
206795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
206895c635efSGarrett D'Amore term_word(p, n->child->string);
206995c635efSGarrett D'Amore return(0);
207095c635efSGarrett D'Amore }
207195c635efSGarrett D'Amore
207295c635efSGarrett D'Amore
207395c635efSGarrett D'Amore /* ARGSUSED */
207495c635efSGarrett D'Amore static void
termp_fo_post(DECL_ARGS)207595c635efSGarrett D'Amore termp_fo_post(DECL_ARGS)
207695c635efSGarrett D'Amore {
207795c635efSGarrett D'Amore
207895c635efSGarrett D'Amore if (MDOC_BODY != n->type)
207995c635efSGarrett D'Amore return;
208095c635efSGarrett D'Amore
208195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
208295c635efSGarrett D'Amore term_word(p, ")");
208395c635efSGarrett D'Amore
208495c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) {
208595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
208695c635efSGarrett D'Amore term_word(p, ";");
2087*698f87a4SGarrett D'Amore term_flushln(p);
208895c635efSGarrett D'Amore }
208995c635efSGarrett D'Amore }
209095c635efSGarrett D'Amore
209195c635efSGarrett D'Amore
209295c635efSGarrett D'Amore /* ARGSUSED */
209395c635efSGarrett D'Amore static int
termp_bf_pre(DECL_ARGS)209495c635efSGarrett D'Amore termp_bf_pre(DECL_ARGS)
209595c635efSGarrett D'Amore {
209695c635efSGarrett D'Amore
209795c635efSGarrett D'Amore if (MDOC_HEAD == n->type)
209895c635efSGarrett D'Amore return(0);
2099*698f87a4SGarrett D'Amore else if (MDOC_BODY != n->type)
210095c635efSGarrett D'Amore return(1);
210195c635efSGarrett D'Amore
210295c635efSGarrett D'Amore if (FONT_Em == n->norm->Bf.font)
210395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
210495c635efSGarrett D'Amore else if (FONT_Sy == n->norm->Bf.font)
210595c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
210695c635efSGarrett D'Amore else
210795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE);
210895c635efSGarrett D'Amore
210995c635efSGarrett D'Amore return(1);
211095c635efSGarrett D'Amore }
211195c635efSGarrett D'Amore
211295c635efSGarrett D'Amore
211395c635efSGarrett D'Amore /* ARGSUSED */
211495c635efSGarrett D'Amore static int
termp_sm_pre(DECL_ARGS)211595c635efSGarrett D'Amore termp_sm_pre(DECL_ARGS)
211695c635efSGarrett D'Amore {
211795c635efSGarrett D'Amore
211895c635efSGarrett D'Amore assert(n->child && MDOC_TEXT == n->child->type);
211995c635efSGarrett D'Amore if (0 == strcmp("on", n->child->string)) {
212095c635efSGarrett D'Amore if (p->col)
212195c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE;
212295c635efSGarrett D'Amore p->flags &= ~TERMP_NONOSPACE;
212395c635efSGarrett D'Amore } else
212495c635efSGarrett D'Amore p->flags |= TERMP_NONOSPACE;
212595c635efSGarrett D'Amore
212695c635efSGarrett D'Amore return(0);
212795c635efSGarrett D'Amore }
212895c635efSGarrett D'Amore
212995c635efSGarrett D'Amore
213095c635efSGarrett D'Amore /* ARGSUSED */
213195c635efSGarrett D'Amore static int
termp_ap_pre(DECL_ARGS)213295c635efSGarrett D'Amore termp_ap_pre(DECL_ARGS)
213395c635efSGarrett D'Amore {
213495c635efSGarrett D'Amore
213595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
213695c635efSGarrett D'Amore term_word(p, "'");
213795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
213895c635efSGarrett D'Amore return(1);
213995c635efSGarrett D'Amore }
214095c635efSGarrett D'Amore
214195c635efSGarrett D'Amore
214295c635efSGarrett D'Amore /* ARGSUSED */
214395c635efSGarrett D'Amore static void
termp____post(DECL_ARGS)214495c635efSGarrett D'Amore termp____post(DECL_ARGS)
214595c635efSGarrett D'Amore {
214695c635efSGarrett D'Amore
214795c635efSGarrett D'Amore /*
214895c635efSGarrett D'Amore * Handle lists of authors. In general, print each followed by
214995c635efSGarrett D'Amore * a comma. Don't print the comma if there are only two
215095c635efSGarrett D'Amore * authors.
215195c635efSGarrett D'Amore */
215295c635efSGarrett D'Amore if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok)
215395c635efSGarrett D'Amore if (NULL == n->next->next || MDOC__A != n->next->next->tok)
215495c635efSGarrett D'Amore if (NULL == n->prev || MDOC__A != n->prev->tok)
215595c635efSGarrett D'Amore return;
215695c635efSGarrett D'Amore
215795c635efSGarrett D'Amore /* TODO: %U. */
215895c635efSGarrett D'Amore
215995c635efSGarrett D'Amore if (NULL == n->parent || MDOC_Rs != n->parent->tok)
216095c635efSGarrett D'Amore return;
216195c635efSGarrett D'Amore
216295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
216395c635efSGarrett D'Amore if (NULL == n->next) {
216495c635efSGarrett D'Amore term_word(p, ".");
216595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE;
216695c635efSGarrett D'Amore } else
216795c635efSGarrett D'Amore term_word(p, ",");
216895c635efSGarrett D'Amore }
216995c635efSGarrett D'Amore
217095c635efSGarrett D'Amore
217195c635efSGarrett D'Amore /* ARGSUSED */
217295c635efSGarrett D'Amore static int
termp_li_pre(DECL_ARGS)217395c635efSGarrett D'Amore termp_li_pre(DECL_ARGS)
217495c635efSGarrett D'Amore {
217595c635efSGarrett D'Amore
217695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE);
217795c635efSGarrett D'Amore return(1);
217895c635efSGarrett D'Amore }
217995c635efSGarrett D'Amore
218095c635efSGarrett D'Amore
218195c635efSGarrett D'Amore /* ARGSUSED */
218295c635efSGarrett D'Amore static int
termp_lk_pre(DECL_ARGS)218395c635efSGarrett D'Amore termp_lk_pre(DECL_ARGS)
218495c635efSGarrett D'Amore {
2185*698f87a4SGarrett D'Amore const struct mdoc_node *link, *descr;
218695c635efSGarrett D'Amore
2187*698f87a4SGarrett D'Amore if (NULL == (link = n->child))
2188*698f87a4SGarrett D'Amore return(0);
2189*698f87a4SGarrett D'Amore
2190*698f87a4SGarrett D'Amore if (NULL != (descr = link->next)) {
219195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
2192*698f87a4SGarrett D'Amore while (NULL != descr) {
2193*698f87a4SGarrett D'Amore term_word(p, descr->string);
2194*698f87a4SGarrett D'Amore descr = descr->next;
2195*698f87a4SGarrett D'Amore }
219695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE;
219795c635efSGarrett D'Amore term_word(p, ":");
2198*698f87a4SGarrett D'Amore term_fontpop(p);
2199*698f87a4SGarrett D'Amore }
220095c635efSGarrett D'Amore
220195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD);
2202*698f87a4SGarrett D'Amore term_word(p, link->string);
220395c635efSGarrett D'Amore term_fontpop(p);
220495c635efSGarrett D'Amore
220595c635efSGarrett D'Amore return(0);
220695c635efSGarrett D'Amore }
220795c635efSGarrett D'Amore
220895c635efSGarrett D'Amore
220995c635efSGarrett D'Amore /* ARGSUSED */
221095c635efSGarrett D'Amore static int
termp_bk_pre(DECL_ARGS)221195c635efSGarrett D'Amore termp_bk_pre(DECL_ARGS)
221295c635efSGarrett D'Amore {
221395c635efSGarrett D'Amore
221495c635efSGarrett D'Amore switch (n->type) {
221595c635efSGarrett D'Amore case (MDOC_BLOCK):
221695c635efSGarrett D'Amore break;
221795c635efSGarrett D'Amore case (MDOC_HEAD):
221895c635efSGarrett D'Amore return(0);
221995c635efSGarrett D'Amore case (MDOC_BODY):
222095c635efSGarrett D'Amore if (n->parent->args || 0 == n->prev->nchild)
222195c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP;
222295c635efSGarrett D'Amore break;
222395c635efSGarrett D'Amore default:
222495c635efSGarrett D'Amore abort();
222595c635efSGarrett D'Amore /* NOTREACHED */
222695c635efSGarrett D'Amore }
222795c635efSGarrett D'Amore
222895c635efSGarrett D'Amore return(1);
222995c635efSGarrett D'Amore }
223095c635efSGarrett D'Amore
223195c635efSGarrett D'Amore
223295c635efSGarrett D'Amore /* ARGSUSED */
223395c635efSGarrett D'Amore static void
termp_bk_post(DECL_ARGS)223495c635efSGarrett D'Amore termp_bk_post(DECL_ARGS)
223595c635efSGarrett D'Amore {
223695c635efSGarrett D'Amore
223795c635efSGarrett D'Amore if (MDOC_BODY == n->type)
223895c635efSGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
223995c635efSGarrett D'Amore }
224095c635efSGarrett D'Amore
224195c635efSGarrett D'Amore /* ARGSUSED */
224295c635efSGarrett D'Amore static void
termp__t_post(DECL_ARGS)224395c635efSGarrett D'Amore termp__t_post(DECL_ARGS)
224495c635efSGarrett D'Amore {
224595c635efSGarrett D'Amore
224695c635efSGarrett D'Amore /*
224795c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote
224895c635efSGarrett D'Amore * us instead of underlining us (for disambiguation).
224995c635efSGarrett D'Amore */
225095c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok &&
225195c635efSGarrett D'Amore n->parent->norm->Rs.quote_T)
2252*698f87a4SGarrett D'Amore termp_quote_post(p, pair, meta, n);
225395c635efSGarrett D'Amore
2254*698f87a4SGarrett D'Amore termp____post(p, pair, meta, n);
225595c635efSGarrett D'Amore }
225695c635efSGarrett D'Amore
225795c635efSGarrett D'Amore /* ARGSUSED */
225895c635efSGarrett D'Amore static int
termp__t_pre(DECL_ARGS)225995c635efSGarrett D'Amore termp__t_pre(DECL_ARGS)
226095c635efSGarrett D'Amore {
226195c635efSGarrett D'Amore
226295c635efSGarrett D'Amore /*
226395c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote
226495c635efSGarrett D'Amore * us instead of underlining us (for disambiguation).
226595c635efSGarrett D'Amore */
226695c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok &&
226795c635efSGarrett D'Amore n->parent->norm->Rs.quote_T)
2268*698f87a4SGarrett D'Amore return(termp_quote_pre(p, pair, meta, n));
226995c635efSGarrett D'Amore
227095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
227195c635efSGarrett D'Amore return(1);
227295c635efSGarrett D'Amore }
227395c635efSGarrett D'Amore
227495c635efSGarrett D'Amore /* ARGSUSED */
227595c635efSGarrett D'Amore static int
termp_under_pre(DECL_ARGS)227695c635efSGarrett D'Amore termp_under_pre(DECL_ARGS)
227795c635efSGarrett D'Amore {
227895c635efSGarrett D'Amore
227995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER);
228095c635efSGarrett D'Amore return(1);
228195c635efSGarrett D'Amore }
2282