xref: /titanic_50/usr/src/cmd/mandoc/mdoc_man.c (revision 260e9a87725c090ba5835b1f9f0b62fa2f96036f)
1*260e9a87SYuri Pankov /*	$Id: mdoc_man.c,v 1.88 2015/02/17 20:37:17 schwarze Exp $ */
295c635efSGarrett D'Amore /*
3*260e9a87SYuri Pankov  * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
495c635efSGarrett D'Amore  *
595c635efSGarrett D'Amore  * Permission to use, copy, modify, and distribute this software for any
695c635efSGarrett D'Amore  * purpose with or without fee is hereby granted, provided that the above
795c635efSGarrett D'Amore  * copyright notice and this permission notice appear in all copies.
895c635efSGarrett D'Amore  *
995c635efSGarrett D'Amore  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1095c635efSGarrett D'Amore  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1195c635efSGarrett D'Amore  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1295c635efSGarrett D'Amore  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1395c635efSGarrett D'Amore  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1495c635efSGarrett D'Amore  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1595c635efSGarrett D'Amore  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1695c635efSGarrett D'Amore  */
1795c635efSGarrett D'Amore #include "config.h"
18*260e9a87SYuri Pankov 
19*260e9a87SYuri Pankov #include <sys/types.h>
2095c635efSGarrett D'Amore 
21698f87a4SGarrett D'Amore #include <assert.h>
2295c635efSGarrett D'Amore #include <stdio.h>
2395c635efSGarrett D'Amore #include <string.h>
2495c635efSGarrett D'Amore 
2595c635efSGarrett D'Amore #include "mandoc.h"
26*260e9a87SYuri Pankov #include "mandoc_aux.h"
27698f87a4SGarrett D'Amore #include "out.h"
2895c635efSGarrett D'Amore #include "man.h"
2995c635efSGarrett D'Amore #include "mdoc.h"
3095c635efSGarrett D'Amore #include "main.h"
3195c635efSGarrett D'Amore 
32*260e9a87SYuri Pankov #define	DECL_ARGS const struct mdoc_meta *meta, struct mdoc_node *n
3395c635efSGarrett D'Amore 
3495c635efSGarrett D'Amore struct	manact {
3595c635efSGarrett D'Amore 	int		(*cond)(DECL_ARGS); /* DON'T run actions */
3695c635efSGarrett D'Amore 	int		(*pre)(DECL_ARGS); /* pre-node action */
3795c635efSGarrett D'Amore 	void		(*post)(DECL_ARGS); /* post-node action */
3895c635efSGarrett D'Amore 	const char	 *prefix; /* pre-node string constant */
3995c635efSGarrett D'Amore 	const char	 *suffix; /* post-node string constant */
4095c635efSGarrett D'Amore };
4195c635efSGarrett D'Amore 
4295c635efSGarrett D'Amore static	int	  cond_body(DECL_ARGS);
4395c635efSGarrett D'Amore static	int	  cond_head(DECL_ARGS);
44698f87a4SGarrett D'Amore static  void	  font_push(char);
45698f87a4SGarrett D'Amore static	void	  font_pop(void);
46698f87a4SGarrett D'Amore static	void	  mid_it(void);
47698f87a4SGarrett D'Amore static	void	  post__t(DECL_ARGS);
48*260e9a87SYuri Pankov static	void	  post_aq(DECL_ARGS);
4995c635efSGarrett D'Amore static	void	  post_bd(DECL_ARGS);
50698f87a4SGarrett D'Amore static	void	  post_bf(DECL_ARGS);
51698f87a4SGarrett D'Amore static	void	  post_bk(DECL_ARGS);
52698f87a4SGarrett D'Amore static	void	  post_bl(DECL_ARGS);
5395c635efSGarrett D'Amore static	void	  post_dl(DECL_ARGS);
54*260e9a87SYuri Pankov static	void	  post_en(DECL_ARGS);
5595c635efSGarrett D'Amore static	void	  post_enc(DECL_ARGS);
56698f87a4SGarrett D'Amore static	void	  post_eo(DECL_ARGS);
57698f87a4SGarrett D'Amore static	void	  post_fa(DECL_ARGS);
58698f87a4SGarrett D'Amore static	void	  post_fd(DECL_ARGS);
59698f87a4SGarrett D'Amore static	void	  post_fl(DECL_ARGS);
60698f87a4SGarrett D'Amore static	void	  post_fn(DECL_ARGS);
61698f87a4SGarrett D'Amore static	void	  post_fo(DECL_ARGS);
62698f87a4SGarrett D'Amore static	void	  post_font(DECL_ARGS);
63698f87a4SGarrett D'Amore static	void	  post_in(DECL_ARGS);
64698f87a4SGarrett D'Amore static	void	  post_it(DECL_ARGS);
65698f87a4SGarrett D'Amore static	void	  post_lb(DECL_ARGS);
6695c635efSGarrett D'Amore static	void	  post_nm(DECL_ARGS);
6795c635efSGarrett D'Amore static	void	  post_percent(DECL_ARGS);
6895c635efSGarrett D'Amore static	void	  post_pf(DECL_ARGS);
6995c635efSGarrett D'Amore static	void	  post_sect(DECL_ARGS);
7095c635efSGarrett D'Amore static	void	  post_sp(DECL_ARGS);
71698f87a4SGarrett D'Amore static	void	  post_vt(DECL_ARGS);
72698f87a4SGarrett D'Amore static	int	  pre__t(DECL_ARGS);
73698f87a4SGarrett D'Amore static	int	  pre_an(DECL_ARGS);
7495c635efSGarrett D'Amore static	int	  pre_ap(DECL_ARGS);
75*260e9a87SYuri Pankov static	int	  pre_aq(DECL_ARGS);
7695c635efSGarrett D'Amore static	int	  pre_bd(DECL_ARGS);
77698f87a4SGarrett D'Amore static	int	  pre_bf(DECL_ARGS);
78698f87a4SGarrett D'Amore static	int	  pre_bk(DECL_ARGS);
79698f87a4SGarrett D'Amore static	int	  pre_bl(DECL_ARGS);
8095c635efSGarrett D'Amore static	int	  pre_br(DECL_ARGS);
8195c635efSGarrett D'Amore static	int	  pre_bx(DECL_ARGS);
8295c635efSGarrett D'Amore static	int	  pre_dl(DECL_ARGS);
83*260e9a87SYuri Pankov static	int	  pre_en(DECL_ARGS);
8495c635efSGarrett D'Amore static	int	  pre_enc(DECL_ARGS);
85698f87a4SGarrett D'Amore static	int	  pre_em(DECL_ARGS);
86*260e9a87SYuri Pankov static	int	  pre_skip(DECL_ARGS);
87*260e9a87SYuri Pankov static	int	  pre_eo(DECL_ARGS);
88*260e9a87SYuri Pankov static	int	  pre_ex(DECL_ARGS);
89698f87a4SGarrett D'Amore static	int	  pre_fa(DECL_ARGS);
90698f87a4SGarrett D'Amore static	int	  pre_fd(DECL_ARGS);
91698f87a4SGarrett D'Amore static	int	  pre_fl(DECL_ARGS);
92698f87a4SGarrett D'Amore static	int	  pre_fn(DECL_ARGS);
93698f87a4SGarrett D'Amore static	int	  pre_fo(DECL_ARGS);
94698f87a4SGarrett D'Amore static	int	  pre_ft(DECL_ARGS);
95698f87a4SGarrett D'Amore static	int	  pre_in(DECL_ARGS);
9695c635efSGarrett D'Amore static	int	  pre_it(DECL_ARGS);
97698f87a4SGarrett D'Amore static	int	  pre_lk(DECL_ARGS);
98698f87a4SGarrett D'Amore static	int	  pre_li(DECL_ARGS);
99*260e9a87SYuri Pankov static	int	  pre_ll(DECL_ARGS);
10095c635efSGarrett D'Amore static	int	  pre_nm(DECL_ARGS);
101698f87a4SGarrett D'Amore static	int	  pre_no(DECL_ARGS);
10295c635efSGarrett D'Amore static	int	  pre_ns(DECL_ARGS);
10395c635efSGarrett D'Amore static	int	  pre_pp(DECL_ARGS);
104698f87a4SGarrett D'Amore static	int	  pre_rs(DECL_ARGS);
105*260e9a87SYuri Pankov static	int	  pre_rv(DECL_ARGS);
106698f87a4SGarrett D'Amore static	int	  pre_sm(DECL_ARGS);
10795c635efSGarrett D'Amore static	int	  pre_sp(DECL_ARGS);
10895c635efSGarrett D'Amore static	int	  pre_sect(DECL_ARGS);
109698f87a4SGarrett D'Amore static	int	  pre_sy(DECL_ARGS);
110698f87a4SGarrett D'Amore static	void	  pre_syn(const struct mdoc_node *);
111698f87a4SGarrett D'Amore static	int	  pre_vt(DECL_ARGS);
11295c635efSGarrett D'Amore static	int	  pre_ux(DECL_ARGS);
11395c635efSGarrett D'Amore static	int	  pre_xr(DECL_ARGS);
114698f87a4SGarrett D'Amore static	void	  print_word(const char *);
115698f87a4SGarrett D'Amore static	void	  print_line(const char *, int);
116698f87a4SGarrett D'Amore static	void	  print_block(const char *, int);
117*260e9a87SYuri Pankov static	void	  print_offs(const char *, int);
118*260e9a87SYuri Pankov static	void	  print_width(const struct mdoc_bl *,
119*260e9a87SYuri Pankov 			const struct mdoc_node *);
120698f87a4SGarrett D'Amore static	void	  print_count(int *);
12195c635efSGarrett D'Amore static	void	  print_node(DECL_ARGS);
12295c635efSGarrett D'Amore 
12395c635efSGarrett D'Amore static	const struct manact manacts[MDOC_MAX + 1] = {
12495c635efSGarrett D'Amore 	{ NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
12595c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Dd */
12695c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Dt */
12795c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Os */
12895c635efSGarrett D'Amore 	{ NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
12995c635efSGarrett D'Amore 	{ NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
13095c635efSGarrett D'Amore 	{ NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
13195c635efSGarrett D'Amore 	{ cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
13295c635efSGarrett D'Amore 	{ cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
13395c635efSGarrett D'Amore 	{ cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
13495c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ed */
135698f87a4SGarrett D'Amore 	{ cond_body, pre_bl, post_bl, NULL, NULL }, /* Bl */
13695c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* El */
137698f87a4SGarrett D'Amore 	{ NULL, pre_it, post_it, NULL, NULL }, /* It */
138698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Ad */
139698f87a4SGarrett D'Amore 	{ NULL, pre_an, NULL, NULL, NULL }, /* An */
140698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Ar */
141698f87a4SGarrett D'Amore 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Cd */
142698f87a4SGarrett D'Amore 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Cm */
143698f87a4SGarrett D'Amore 	{ NULL, pre_li, post_font, NULL, NULL }, /* Dv */
144698f87a4SGarrett D'Amore 	{ NULL, pre_li, post_font, NULL, NULL }, /* Er */
145698f87a4SGarrett D'Amore 	{ NULL, pre_li, post_font, NULL, NULL }, /* Ev */
146*260e9a87SYuri Pankov 	{ NULL, pre_ex, NULL, NULL, NULL }, /* Ex */
147698f87a4SGarrett D'Amore 	{ NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
148698f87a4SGarrett D'Amore 	{ NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
149698f87a4SGarrett D'Amore 	{ NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
150698f87a4SGarrett D'Amore 	{ NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */
151698f87a4SGarrett D'Amore 	{ NULL, pre_ft, post_font, NULL, NULL }, /* Ft */
152698f87a4SGarrett D'Amore 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Ic */
153698f87a4SGarrett D'Amore 	{ NULL, pre_in, post_in, NULL, NULL }, /* In */
154698f87a4SGarrett D'Amore 	{ NULL, pre_li, post_font, NULL, NULL }, /* Li */
15595c635efSGarrett D'Amore 	{ cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
15695c635efSGarrett D'Amore 	{ NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
15795c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
158*260e9a87SYuri Pankov 	{ NULL, pre_ft, post_font, NULL, NULL }, /* Ot */
159698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Pa */
160*260e9a87SYuri Pankov 	{ NULL, pre_rv, NULL, NULL, NULL }, /* Rv */
16195c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* St */
162698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Va */
163698f87a4SGarrett D'Amore 	{ NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
16495c635efSGarrett D'Amore 	{ NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
165698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %A */
166698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_percent, NULL, NULL }, /* %B */
167698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %D */
168698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_percent, NULL, NULL }, /* %I */
169698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_percent, NULL, NULL }, /* %J */
170698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %N */
171698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %O */
172698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %P */
173698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %R */
174698f87a4SGarrett D'Amore 	{ NULL, pre__t, post__t, NULL, NULL }, /* %T */
175698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %V */
17695c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ac */
177*260e9a87SYuri Pankov 	{ cond_body, pre_aq, post_aq, NULL, NULL }, /* Ao */
178*260e9a87SYuri Pankov 	{ cond_body, pre_aq, post_aq, NULL, NULL }, /* Aq */
17995c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* At */
18095c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Bc */
181698f87a4SGarrett D'Amore 	{ NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
18295c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
18395c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
18495c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
18595c635efSGarrett D'Amore 	{ NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
186*260e9a87SYuri Pankov 	{ NULL, pre_skip, NULL, NULL, NULL }, /* Db */
18795c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Dc */
188*260e9a87SYuri Pankov 	{ cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
189*260e9a87SYuri Pankov 	{ cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Dq */
190698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ec */
191698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ef */
192698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Em */
193*260e9a87SYuri Pankov 	{ cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
19495c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
195698f87a4SGarrett D'Amore 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
196698f87a4SGarrett D'Amore 	{ NULL, pre_no, NULL, NULL, NULL }, /* No */
19795c635efSGarrett D'Amore 	{ NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
19895c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
19995c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
20095c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Pc */
20195c635efSGarrett D'Amore 	{ NULL, NULL, post_pf, NULL, NULL }, /* Pf */
20295c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
20395c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
20495c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Qc */
205698f87a4SGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Ql */
20695c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
20795c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
20895c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Re */
209698f87a4SGarrett D'Amore 	{ cond_body, pre_rs, NULL, NULL, NULL }, /* Rs */
21095c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Sc */
211698f87a4SGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* So */
212698f87a4SGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Sq */
213698f87a4SGarrett D'Amore 	{ NULL, pre_sm, NULL, NULL, NULL }, /* Sm */
214698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Sx */
215698f87a4SGarrett D'Amore 	{ NULL, pre_sy, post_font, NULL, NULL }, /* Sy */
216698f87a4SGarrett D'Amore 	{ NULL, pre_li, post_font, NULL, NULL }, /* Tn */
21795c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
218698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Xc */
219698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Xo */
220698f87a4SGarrett D'Amore 	{ NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
221698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Fc */
22295c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
22395c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Oc */
224698f87a4SGarrett D'Amore 	{ NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
225698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ek */
22695c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
22795c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Hf */
228*260e9a87SYuri Pankov 	{ NULL, pre_em, post_font, NULL, NULL }, /* Fr */
22995c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
230698f87a4SGarrett D'Amore 	{ NULL, NULL, post_lb, NULL, NULL }, /* Lb */
23195c635efSGarrett D'Amore 	{ NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
232698f87a4SGarrett D'Amore 	{ NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
233698f87a4SGarrett D'Amore 	{ NULL, pre_em, post_font, NULL, NULL }, /* Mt */
23495c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
23595c635efSGarrett D'Amore 	{ cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
23695c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Brc */
237698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %C */
238*260e9a87SYuri Pankov 	{ NULL, pre_skip, NULL, NULL, NULL }, /* Es */
239*260e9a87SYuri Pankov 	{ cond_body, pre_en, post_en, NULL, NULL }, /* En */
24095c635efSGarrett D'Amore 	{ NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
241698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
24295c635efSGarrett D'Amore 	{ NULL, pre_br, NULL, NULL, NULL }, /* br */
24395c635efSGarrett D'Amore 	{ NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
244698f87a4SGarrett D'Amore 	{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
245698f87a4SGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
246*260e9a87SYuri Pankov 	{ NULL, pre_ll, post_sp, NULL, NULL }, /* ll */
24795c635efSGarrett D'Amore 	{ NULL, NULL, NULL, NULL, NULL }, /* ROOT */
24895c635efSGarrett D'Amore };
24995c635efSGarrett D'Amore 
250698f87a4SGarrett D'Amore static	int		outflags;
251698f87a4SGarrett D'Amore #define	MMAN_spc	(1 << 0)  /* blank character before next word */
252698f87a4SGarrett D'Amore #define	MMAN_spc_force	(1 << 1)  /* even before trailing punctuation */
253698f87a4SGarrett D'Amore #define	MMAN_nl		(1 << 2)  /* break man(7) code line */
254698f87a4SGarrett D'Amore #define	MMAN_br		(1 << 3)  /* break output line */
255698f87a4SGarrett D'Amore #define	MMAN_sp		(1 << 4)  /* insert a blank output line */
256698f87a4SGarrett D'Amore #define	MMAN_PP		(1 << 5)  /* reset indentation etc. */
257698f87a4SGarrett D'Amore #define	MMAN_Sm		(1 << 6)  /* horizontal spacing mode */
258698f87a4SGarrett D'Amore #define	MMAN_Bk		(1 << 7)  /* word keep mode */
259698f87a4SGarrett D'Amore #define	MMAN_Bk_susp	(1 << 8)  /* suspend this (after a macro) */
260698f87a4SGarrett D'Amore #define	MMAN_An_split	(1 << 9)  /* author mode is "split" */
261698f87a4SGarrett D'Amore #define	MMAN_An_nosplit	(1 << 10) /* author mode is "nosplit" */
262698f87a4SGarrett D'Amore #define	MMAN_PD		(1 << 11) /* inter-paragraph spacing disabled */
263698f87a4SGarrett D'Amore #define	MMAN_nbrword	(1 << 12) /* do not break the next word */
264698f87a4SGarrett D'Amore 
265698f87a4SGarrett D'Amore #define	BL_STACK_MAX	32
266698f87a4SGarrett D'Amore 
267*260e9a87SYuri Pankov static	int		Bl_stack[BL_STACK_MAX];  /* offsets [chars] */
268698f87a4SGarrett D'Amore static	int		Bl_stack_post[BL_STACK_MAX];  /* add final .RE */
269698f87a4SGarrett D'Amore static	int		Bl_stack_len;  /* number of nested Bl blocks */
270698f87a4SGarrett D'Amore static	int		TPremain;  /* characters before tag is full */
271698f87a4SGarrett D'Amore 
272698f87a4SGarrett D'Amore static	struct {
273698f87a4SGarrett D'Amore 	char	*head;
274698f87a4SGarrett D'Amore 	char	*tail;
275698f87a4SGarrett D'Amore 	size_t	 size;
276698f87a4SGarrett D'Amore }	fontqueue;
277698f87a4SGarrett D'Amore 
278*260e9a87SYuri Pankov 
27995c635efSGarrett D'Amore static void
font_push(char newfont)280698f87a4SGarrett D'Amore font_push(char newfont)
28195c635efSGarrett D'Amore {
28295c635efSGarrett D'Amore 
283698f87a4SGarrett D'Amore 	if (fontqueue.head + fontqueue.size <= ++fontqueue.tail) {
284698f87a4SGarrett D'Amore 		fontqueue.size += 8;
285698f87a4SGarrett D'Amore 		fontqueue.head = mandoc_realloc(fontqueue.head,
286698f87a4SGarrett D'Amore 		    fontqueue.size);
287698f87a4SGarrett D'Amore 	}
288698f87a4SGarrett D'Amore 	*fontqueue.tail = newfont;
289698f87a4SGarrett D'Amore 	print_word("");
290698f87a4SGarrett D'Amore 	printf("\\f");
291698f87a4SGarrett D'Amore 	putchar(newfont);
292698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
293698f87a4SGarrett D'Amore }
294698f87a4SGarrett D'Amore 
295698f87a4SGarrett D'Amore static void
font_pop(void)296698f87a4SGarrett D'Amore font_pop(void)
297698f87a4SGarrett D'Amore {
298698f87a4SGarrett D'Amore 
299698f87a4SGarrett D'Amore 	if (fontqueue.tail > fontqueue.head)
300698f87a4SGarrett D'Amore 		fontqueue.tail--;
301698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
302698f87a4SGarrett D'Amore 	print_word("");
303698f87a4SGarrett D'Amore 	printf("\\f");
304698f87a4SGarrett D'Amore 	putchar(*fontqueue.tail);
305698f87a4SGarrett D'Amore }
306698f87a4SGarrett D'Amore 
307698f87a4SGarrett D'Amore static void
print_word(const char * s)308698f87a4SGarrett D'Amore print_word(const char *s)
309698f87a4SGarrett D'Amore {
310698f87a4SGarrett D'Amore 
311698f87a4SGarrett D'Amore 	if ((MMAN_PP | MMAN_sp | MMAN_br | MMAN_nl) & outflags) {
31295c635efSGarrett D'Amore 		/*
31395c635efSGarrett D'Amore 		 * If we need a newline, print it now and start afresh.
31495c635efSGarrett D'Amore 		 */
315698f87a4SGarrett D'Amore 		if (MMAN_PP & outflags) {
316698f87a4SGarrett D'Amore 			if (MMAN_sp & outflags) {
317698f87a4SGarrett D'Amore 				if (MMAN_PD & outflags) {
318698f87a4SGarrett D'Amore 					printf("\n.PD");
319698f87a4SGarrett D'Amore 					outflags &= ~MMAN_PD;
320698f87a4SGarrett D'Amore 				}
321698f87a4SGarrett D'Amore 			} else if ( ! (MMAN_PD & outflags)) {
322698f87a4SGarrett D'Amore 				printf("\n.PD 0");
323698f87a4SGarrett D'Amore 				outflags |= MMAN_PD;
324698f87a4SGarrett D'Amore 			}
325698f87a4SGarrett D'Amore 			printf("\n.PP\n");
326698f87a4SGarrett D'Amore 		} else if (MMAN_sp & outflags)
327698f87a4SGarrett D'Amore 			printf("\n.sp\n");
328698f87a4SGarrett D'Amore 		else if (MMAN_br & outflags)
329698f87a4SGarrett D'Amore 			printf("\n.br\n");
330698f87a4SGarrett D'Amore 		else if (MMAN_nl & outflags)
33195c635efSGarrett D'Amore 			putchar('\n');
332698f87a4SGarrett D'Amore 		outflags &= ~(MMAN_PP|MMAN_sp|MMAN_br|MMAN_nl|MMAN_spc);
333698f87a4SGarrett D'Amore 		if (1 == TPremain)
334698f87a4SGarrett D'Amore 			printf(".br\n");
335698f87a4SGarrett D'Amore 		TPremain = 0;
336698f87a4SGarrett D'Amore 	} else if (MMAN_spc & outflags) {
33795c635efSGarrett D'Amore 		/*
338698f87a4SGarrett D'Amore 		 * If we need a space, only print it if
339698f87a4SGarrett D'Amore 		 * (1) it is forced by `No' or
340698f87a4SGarrett D'Amore 		 * (2) what follows is not terminating punctuation or
341698f87a4SGarrett D'Amore 		 * (3) what follows is longer than one character.
34295c635efSGarrett D'Amore 		 */
343698f87a4SGarrett D'Amore 		if (MMAN_spc_force & outflags || '\0' == s[0] ||
344698f87a4SGarrett D'Amore 		    NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
345698f87a4SGarrett D'Amore 			if (MMAN_Bk & outflags &&
346698f87a4SGarrett D'Amore 			    ! (MMAN_Bk_susp & outflags))
347698f87a4SGarrett D'Amore 				putchar('\\');
34895c635efSGarrett D'Amore 			putchar(' ');
349698f87a4SGarrett D'Amore 			if (TPremain)
350698f87a4SGarrett D'Amore 				TPremain--;
351698f87a4SGarrett D'Amore 		}
352698f87a4SGarrett D'Amore 	}
35395c635efSGarrett D'Amore 
35495c635efSGarrett D'Amore 	/*
35595c635efSGarrett D'Amore 	 * Reassign needing space if we're not following opening
35695c635efSGarrett D'Amore 	 * punctuation.
35795c635efSGarrett D'Amore 	 */
358698f87a4SGarrett D'Amore 	if (MMAN_Sm & outflags && ('\0' == s[0] ||
359698f87a4SGarrett D'Amore 	    (('(' != s[0] && '[' != s[0]) || '\0' != s[1])))
360698f87a4SGarrett D'Amore 		outflags |= MMAN_spc;
361698f87a4SGarrett D'Amore 	else
362698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
363698f87a4SGarrett D'Amore 	outflags &= ~(MMAN_spc_force | MMAN_Bk_susp);
36495c635efSGarrett D'Amore 
36595c635efSGarrett D'Amore 	for ( ; *s; s++) {
36695c635efSGarrett D'Amore 		switch (*s) {
367*260e9a87SYuri Pankov 		case ASCII_NBRSP:
368698f87a4SGarrett D'Amore 			printf("\\ ");
36995c635efSGarrett D'Amore 			break;
370*260e9a87SYuri Pankov 		case ASCII_HYPH:
37195c635efSGarrett D'Amore 			putchar('-');
37295c635efSGarrett D'Amore 			break;
373*260e9a87SYuri Pankov 		case ASCII_BREAK:
374*260e9a87SYuri Pankov 			printf("\\:");
375*260e9a87SYuri Pankov 			break;
376*260e9a87SYuri Pankov 		case ' ':
377698f87a4SGarrett D'Amore 			if (MMAN_nbrword & outflags) {
378698f87a4SGarrett D'Amore 				printf("\\ ");
379698f87a4SGarrett D'Amore 				break;
380698f87a4SGarrett D'Amore 			}
381698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
38295c635efSGarrett D'Amore 		default:
38395c635efSGarrett D'Amore 			putchar((unsigned char)*s);
38495c635efSGarrett D'Amore 			break;
38595c635efSGarrett D'Amore 		}
386698f87a4SGarrett D'Amore 		if (TPremain)
387698f87a4SGarrett D'Amore 			TPremain--;
38895c635efSGarrett D'Amore 	}
389698f87a4SGarrett D'Amore 	outflags &= ~MMAN_nbrword;
390698f87a4SGarrett D'Amore }
391698f87a4SGarrett D'Amore 
392698f87a4SGarrett D'Amore static void
print_line(const char * s,int newflags)393698f87a4SGarrett D'Amore print_line(const char *s, int newflags)
394698f87a4SGarrett D'Amore {
395698f87a4SGarrett D'Amore 
396698f87a4SGarrett D'Amore 	outflags &= ~MMAN_br;
397698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
398698f87a4SGarrett D'Amore 	print_word(s);
399698f87a4SGarrett D'Amore 	outflags |= newflags;
400698f87a4SGarrett D'Amore }
401698f87a4SGarrett D'Amore 
402698f87a4SGarrett D'Amore static void
print_block(const char * s,int newflags)403698f87a4SGarrett D'Amore print_block(const char *s, int newflags)
404698f87a4SGarrett D'Amore {
405698f87a4SGarrett D'Amore 
406698f87a4SGarrett D'Amore 	outflags &= ~MMAN_PP;
407698f87a4SGarrett D'Amore 	if (MMAN_sp & outflags) {
408698f87a4SGarrett D'Amore 		outflags &= ~(MMAN_sp | MMAN_br);
409698f87a4SGarrett D'Amore 		if (MMAN_PD & outflags) {
410698f87a4SGarrett D'Amore 			print_line(".PD", 0);
411698f87a4SGarrett D'Amore 			outflags &= ~MMAN_PD;
412698f87a4SGarrett D'Amore 		}
413698f87a4SGarrett D'Amore 	} else if (! (MMAN_PD & outflags))
414698f87a4SGarrett D'Amore 		print_line(".PD 0", MMAN_PD);
415698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
416698f87a4SGarrett D'Amore 	print_word(s);
417698f87a4SGarrett D'Amore 	outflags |= MMAN_Bk_susp | newflags;
418698f87a4SGarrett D'Amore }
419698f87a4SGarrett D'Amore 
420698f87a4SGarrett D'Amore static void
print_offs(const char * v,int keywords)421*260e9a87SYuri Pankov print_offs(const char *v, int keywords)
422698f87a4SGarrett D'Amore {
423698f87a4SGarrett D'Amore 	char		  buf[24];
424698f87a4SGarrett D'Amore 	struct roffsu	  su;
425*260e9a87SYuri Pankov 	int		  sz;
426698f87a4SGarrett D'Amore 
427698f87a4SGarrett D'Amore 	print_line(".RS", MMAN_Bk_susp);
428698f87a4SGarrett D'Amore 
429698f87a4SGarrett D'Amore 	/* Convert v into a number (of characters). */
430*260e9a87SYuri Pankov 	if (NULL == v || '\0' == *v || (keywords && !strcmp(v, "left")))
431698f87a4SGarrett D'Amore 		sz = 0;
432*260e9a87SYuri Pankov 	else if (keywords && !strcmp(v, "indent"))
433698f87a4SGarrett D'Amore 		sz = 6;
434*260e9a87SYuri Pankov 	else if (keywords && !strcmp(v, "indent-two"))
435698f87a4SGarrett D'Amore 		sz = 12;
436*260e9a87SYuri Pankov 	else if (a2roffsu(v, &su, SCALE_EN) > 1) {
437698f87a4SGarrett D'Amore 		if (SCALE_EN == su.unit)
438698f87a4SGarrett D'Amore 			sz = su.scale;
439698f87a4SGarrett D'Amore 		else {
440698f87a4SGarrett D'Amore 			/*
441698f87a4SGarrett D'Amore 			 * XXX
442698f87a4SGarrett D'Amore 			 * If we are inside an enclosing list,
443698f87a4SGarrett D'Amore 			 * there is no easy way to add the two
444698f87a4SGarrett D'Amore 			 * indentations because they are provided
445698f87a4SGarrett D'Amore 			 * in terms of different units.
446698f87a4SGarrett D'Amore 			 */
447698f87a4SGarrett D'Amore 			print_word(v);
448698f87a4SGarrett D'Amore 			outflags |= MMAN_nl;
449698f87a4SGarrett D'Amore 			return;
450698f87a4SGarrett D'Amore 		}
451698f87a4SGarrett D'Amore 	} else
452698f87a4SGarrett D'Amore 		sz = strlen(v);
453698f87a4SGarrett D'Amore 
454698f87a4SGarrett D'Amore 	/*
455698f87a4SGarrett D'Amore 	 * We are inside an enclosing list.
456698f87a4SGarrett D'Amore 	 * Add the two indentations.
457698f87a4SGarrett D'Amore 	 */
458698f87a4SGarrett D'Amore 	if (Bl_stack_len)
459698f87a4SGarrett D'Amore 		sz += Bl_stack[Bl_stack_len - 1];
460698f87a4SGarrett D'Amore 
461*260e9a87SYuri Pankov 	(void)snprintf(buf, sizeof(buf), "%dn", sz);
462698f87a4SGarrett D'Amore 	print_word(buf);
463698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
464698f87a4SGarrett D'Amore }
465698f87a4SGarrett D'Amore 
466698f87a4SGarrett D'Amore /*
467698f87a4SGarrett D'Amore  * Set up the indentation for a list item; used from pre_it().
468698f87a4SGarrett D'Amore  */
469*260e9a87SYuri Pankov static void
print_width(const struct mdoc_bl * bl,const struct mdoc_node * child)470*260e9a87SYuri Pankov print_width(const struct mdoc_bl *bl, const struct mdoc_node *child)
471698f87a4SGarrett D'Amore {
472698f87a4SGarrett D'Amore 	char		  buf[24];
473698f87a4SGarrett D'Amore 	struct roffsu	  su;
474*260e9a87SYuri Pankov 	int		  numeric, remain, sz, chsz;
475698f87a4SGarrett D'Amore 
476698f87a4SGarrett D'Amore 	numeric = 1;
477698f87a4SGarrett D'Amore 	remain = 0;
478698f87a4SGarrett D'Amore 
479*260e9a87SYuri Pankov 	/* Convert the width into a number (of characters). */
480*260e9a87SYuri Pankov 	if (bl->width == NULL)
481*260e9a87SYuri Pankov 		sz = (bl->type == LIST_hang) ? 6 : 0;
482*260e9a87SYuri Pankov 	else if (a2roffsu(bl->width, &su, SCALE_MAX) > 1) {
483698f87a4SGarrett D'Amore 		if (SCALE_EN == su.unit)
484698f87a4SGarrett D'Amore 			sz = su.scale;
485698f87a4SGarrett D'Amore 		else {
486698f87a4SGarrett D'Amore 			sz = 0;
487698f87a4SGarrett D'Amore 			numeric = 0;
488698f87a4SGarrett D'Amore 		}
489698f87a4SGarrett D'Amore 	} else
490*260e9a87SYuri Pankov 		sz = strlen(bl->width);
491698f87a4SGarrett D'Amore 
492698f87a4SGarrett D'Amore 	/* XXX Rough estimation, might have multiple parts. */
493*260e9a87SYuri Pankov 	if (bl->type == LIST_enum)
494*260e9a87SYuri Pankov 		chsz = (bl->count > 8) + 1;
495*260e9a87SYuri Pankov 	else if (child != NULL && child->type == MDOC_TEXT)
496*260e9a87SYuri Pankov 		chsz = strlen(child->string);
497*260e9a87SYuri Pankov 	else
498*260e9a87SYuri Pankov 		chsz = 0;
499698f87a4SGarrett D'Amore 
500698f87a4SGarrett D'Amore 	/* Maybe we are inside an enclosing list? */
501698f87a4SGarrett D'Amore 	mid_it();
502698f87a4SGarrett D'Amore 
503698f87a4SGarrett D'Amore 	/*
504698f87a4SGarrett D'Amore 	 * Save our own indentation,
505698f87a4SGarrett D'Amore 	 * such that child lists can use it.
506698f87a4SGarrett D'Amore 	 */
507698f87a4SGarrett D'Amore 	Bl_stack[Bl_stack_len++] = sz + 2;
508698f87a4SGarrett D'Amore 
509698f87a4SGarrett D'Amore 	/* Set up the current list. */
510*260e9a87SYuri Pankov 	if (chsz > sz && bl->type != LIST_tag)
511698f87a4SGarrett D'Amore 		print_block(".HP", 0);
512698f87a4SGarrett D'Amore 	else {
513698f87a4SGarrett D'Amore 		print_block(".TP", 0);
514698f87a4SGarrett D'Amore 		remain = sz + 2;
515698f87a4SGarrett D'Amore 	}
516698f87a4SGarrett D'Amore 	if (numeric) {
517*260e9a87SYuri Pankov 		(void)snprintf(buf, sizeof(buf), "%dn", sz + 2);
518698f87a4SGarrett D'Amore 		print_word(buf);
519698f87a4SGarrett D'Amore 	} else
520*260e9a87SYuri Pankov 		print_word(bl->width);
521698f87a4SGarrett D'Amore 	TPremain = remain;
522698f87a4SGarrett D'Amore }
523698f87a4SGarrett D'Amore 
524*260e9a87SYuri Pankov static void
print_count(int * count)525698f87a4SGarrett D'Amore print_count(int *count)
526698f87a4SGarrett D'Amore {
527*260e9a87SYuri Pankov 	char		  buf[24];
528698f87a4SGarrett D'Amore 
529*260e9a87SYuri Pankov 	(void)snprintf(buf, sizeof(buf), "%d.\\&", ++*count);
530698f87a4SGarrett D'Amore 	print_word(buf);
53195c635efSGarrett D'Amore }
53295c635efSGarrett D'Amore 
53395c635efSGarrett D'Amore void
man_man(void * arg,const struct man * man)53495c635efSGarrett D'Amore man_man(void *arg, const struct man *man)
53595c635efSGarrett D'Amore {
53695c635efSGarrett D'Amore 
53795c635efSGarrett D'Amore 	/*
53895c635efSGarrett D'Amore 	 * Dump the keep buffer.
53995c635efSGarrett D'Amore 	 * We're guaranteed by now that this exists (is non-NULL).
54095c635efSGarrett D'Amore 	 * Flush stdout afterward, just in case.
54195c635efSGarrett D'Amore 	 */
54295c635efSGarrett D'Amore 	fputs(mparse_getkeep(man_mparse(man)), stdout);
54395c635efSGarrett D'Amore 	fflush(stdout);
54495c635efSGarrett D'Amore }
54595c635efSGarrett D'Amore 
54695c635efSGarrett D'Amore void
man_mdoc(void * arg,const struct mdoc * mdoc)54795c635efSGarrett D'Amore man_mdoc(void *arg, const struct mdoc *mdoc)
54895c635efSGarrett D'Amore {
549698f87a4SGarrett D'Amore 	const struct mdoc_meta *meta;
550*260e9a87SYuri Pankov 	struct mdoc_node *n;
55195c635efSGarrett D'Amore 
552698f87a4SGarrett D'Amore 	meta = mdoc_meta(mdoc);
553*260e9a87SYuri Pankov 	n = mdoc_node(mdoc)->child;
55495c635efSGarrett D'Amore 
555698f87a4SGarrett D'Amore 	printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
556*260e9a87SYuri Pankov 	    meta->title,
557*260e9a87SYuri Pankov 	    (meta->msec == NULL ? "" : meta->msec),
558*260e9a87SYuri Pankov 	    meta->date, meta->os, meta->vol);
55995c635efSGarrett D'Amore 
560698f87a4SGarrett D'Amore 	/* Disable hyphenation and if nroff, disable justification. */
561698f87a4SGarrett D'Amore 	printf(".nh\n.if n .ad l");
56295c635efSGarrett D'Amore 
563698f87a4SGarrett D'Amore 	outflags = MMAN_nl | MMAN_Sm;
564698f87a4SGarrett D'Amore 	if (0 == fontqueue.size) {
565698f87a4SGarrett D'Amore 		fontqueue.size = 8;
566698f87a4SGarrett D'Amore 		fontqueue.head = fontqueue.tail = mandoc_malloc(8);
567698f87a4SGarrett D'Amore 		*fontqueue.tail = 'R';
568698f87a4SGarrett D'Amore 	}
569*260e9a87SYuri Pankov 	while (n != NULL) {
570698f87a4SGarrett D'Amore 		print_node(meta, n);
571*260e9a87SYuri Pankov 		n = n->next;
572*260e9a87SYuri Pankov 	}
57395c635efSGarrett D'Amore 	putchar('\n');
57495c635efSGarrett D'Amore }
57595c635efSGarrett D'Amore 
57695c635efSGarrett D'Amore static void
print_node(DECL_ARGS)57795c635efSGarrett D'Amore print_node(DECL_ARGS)
57895c635efSGarrett D'Amore {
57995c635efSGarrett D'Amore 	const struct manact	*act;
580*260e9a87SYuri Pankov 	struct mdoc_node	*sub;
58195c635efSGarrett D'Amore 	int			 cond, do_sub;
58295c635efSGarrett D'Amore 
58395c635efSGarrett D'Amore 	/*
58495c635efSGarrett D'Amore 	 * Break the line if we were parsed subsequent the current node.
58595c635efSGarrett D'Amore 	 * This makes the page structure be more consistent.
58695c635efSGarrett D'Amore 	 */
587698f87a4SGarrett D'Amore 	if (MMAN_spc & outflags && MDOC_LINE & n->flags)
588698f87a4SGarrett D'Amore 		outflags |= MMAN_nl;
58995c635efSGarrett D'Amore 
59095c635efSGarrett D'Amore 	act = NULL;
59195c635efSGarrett D'Amore 	cond = 0;
59295c635efSGarrett D'Amore 	do_sub = 1;
593*260e9a87SYuri Pankov 	n->flags &= ~MDOC_ENDED;
59495c635efSGarrett D'Amore 
59595c635efSGarrett D'Amore 	if (MDOC_TEXT == n->type) {
59695c635efSGarrett D'Amore 		/*
59795c635efSGarrett D'Amore 		 * Make sure that we don't happen to start with a
59895c635efSGarrett D'Amore 		 * control character at the start of a line.
59995c635efSGarrett D'Amore 		 */
600*260e9a87SYuri Pankov 		if (MMAN_nl & outflags &&
601*260e9a87SYuri Pankov 		    ('.' == *n->string || '\'' == *n->string)) {
602698f87a4SGarrett D'Amore 			print_word("");
603698f87a4SGarrett D'Amore 			printf("\\&");
604698f87a4SGarrett D'Amore 			outflags &= ~MMAN_spc;
60595c635efSGarrett D'Amore 		}
606*260e9a87SYuri Pankov 		if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMC))
607*260e9a87SYuri Pankov 			outflags |= MMAN_spc_force;
608698f87a4SGarrett D'Amore 		print_word(n->string);
609*260e9a87SYuri Pankov 		if (outflags & MMAN_Sm && ! (n->flags & MDOC_DELIMO))
610*260e9a87SYuri Pankov 			outflags |= MMAN_spc;
61195c635efSGarrett D'Amore 	} else {
61295c635efSGarrett D'Amore 		/*
61395c635efSGarrett D'Amore 		 * Conditionally run the pre-node action handler for a
61495c635efSGarrett D'Amore 		 * node.
61595c635efSGarrett D'Amore 		 */
61695c635efSGarrett D'Amore 		act = manacts + n->tok;
617*260e9a87SYuri Pankov 		cond = act->cond == NULL || (*act->cond)(meta, n);
618*260e9a87SYuri Pankov 		if (cond && act->pre && (n->end == ENDBODY_NOT || n->nchild))
619698f87a4SGarrett D'Amore 			do_sub = (*act->pre)(meta, n);
62095c635efSGarrett D'Amore 	}
62195c635efSGarrett D'Amore 
62295c635efSGarrett D'Amore 	/*
62395c635efSGarrett D'Amore 	 * Conditionally run all child nodes.
62495c635efSGarrett D'Amore 	 * Note that this iterates over children instead of using
62595c635efSGarrett D'Amore 	 * recursion.  This prevents unnecessary depth in the stack.
62695c635efSGarrett D'Amore 	 */
62795c635efSGarrett D'Amore 	if (do_sub)
62895c635efSGarrett D'Amore 		for (sub = n->child; sub; sub = sub->next)
629698f87a4SGarrett D'Amore 			print_node(meta, sub);
63095c635efSGarrett D'Amore 
63195c635efSGarrett D'Amore 	/*
63295c635efSGarrett D'Amore 	 * Lastly, conditionally run the post-node handler.
63395c635efSGarrett D'Amore 	 */
634*260e9a87SYuri Pankov 	if (MDOC_ENDED & n->flags)
635*260e9a87SYuri Pankov 		return;
636*260e9a87SYuri Pankov 
63795c635efSGarrett D'Amore 	if (cond && act->post)
638698f87a4SGarrett D'Amore 		(*act->post)(meta, n);
639*260e9a87SYuri Pankov 
640*260e9a87SYuri Pankov 	if (ENDBODY_NOT != n->end)
641*260e9a87SYuri Pankov 		n->body->flags |= MDOC_ENDED;
642*260e9a87SYuri Pankov 
643*260e9a87SYuri Pankov 	if (ENDBODY_NOSPACE == n->end)
644*260e9a87SYuri Pankov 		outflags &= ~(MMAN_spc | MMAN_nl);
64595c635efSGarrett D'Amore }
64695c635efSGarrett D'Amore 
64795c635efSGarrett D'Amore static int
cond_head(DECL_ARGS)64895c635efSGarrett D'Amore cond_head(DECL_ARGS)
64995c635efSGarrett D'Amore {
65095c635efSGarrett D'Amore 
65195c635efSGarrett D'Amore 	return(MDOC_HEAD == n->type);
65295c635efSGarrett D'Amore }
65395c635efSGarrett D'Amore 
65495c635efSGarrett D'Amore static int
cond_body(DECL_ARGS)65595c635efSGarrett D'Amore cond_body(DECL_ARGS)
65695c635efSGarrett D'Amore {
65795c635efSGarrett D'Amore 
65895c635efSGarrett D'Amore 	return(MDOC_BODY == n->type);
65995c635efSGarrett D'Amore }
66095c635efSGarrett D'Amore 
66195c635efSGarrett D'Amore static int
pre_enc(DECL_ARGS)66295c635efSGarrett D'Amore pre_enc(DECL_ARGS)
66395c635efSGarrett D'Amore {
66495c635efSGarrett D'Amore 	const char	*prefix;
66595c635efSGarrett D'Amore 
66695c635efSGarrett D'Amore 	prefix = manacts[n->tok].prefix;
66795c635efSGarrett D'Amore 	if (NULL == prefix)
66895c635efSGarrett D'Amore 		return(1);
669698f87a4SGarrett D'Amore 	print_word(prefix);
670698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
67195c635efSGarrett D'Amore 	return(1);
67295c635efSGarrett D'Amore }
67395c635efSGarrett D'Amore 
67495c635efSGarrett D'Amore static void
post_enc(DECL_ARGS)67595c635efSGarrett D'Amore post_enc(DECL_ARGS)
67695c635efSGarrett D'Amore {
67795c635efSGarrett D'Amore 	const char *suffix;
67895c635efSGarrett D'Amore 
67995c635efSGarrett D'Amore 	suffix = manacts[n->tok].suffix;
68095c635efSGarrett D'Amore 	if (NULL == suffix)
68195c635efSGarrett D'Amore 		return;
682*260e9a87SYuri Pankov 	outflags &= ~(MMAN_spc | MMAN_nl);
683698f87a4SGarrett D'Amore 	print_word(suffix);
68495c635efSGarrett D'Amore }
68595c635efSGarrett D'Amore 
686*260e9a87SYuri Pankov static int
pre_ex(DECL_ARGS)687*260e9a87SYuri Pankov pre_ex(DECL_ARGS)
688*260e9a87SYuri Pankov {
689*260e9a87SYuri Pankov 	int	 nchild;
690*260e9a87SYuri Pankov 
691*260e9a87SYuri Pankov 	outflags |= MMAN_br | MMAN_nl;
692*260e9a87SYuri Pankov 
693*260e9a87SYuri Pankov 	print_word("The");
694*260e9a87SYuri Pankov 
695*260e9a87SYuri Pankov 	nchild = n->nchild;
696*260e9a87SYuri Pankov 	for (n = n->child; n; n = n->next) {
697*260e9a87SYuri Pankov 		font_push('B');
698*260e9a87SYuri Pankov 		print_word(n->string);
699*260e9a87SYuri Pankov 		font_pop();
700*260e9a87SYuri Pankov 
701*260e9a87SYuri Pankov 		if (n->next == NULL)
702*260e9a87SYuri Pankov 			continue;
703*260e9a87SYuri Pankov 
704*260e9a87SYuri Pankov 		if (nchild > 2) {
705*260e9a87SYuri Pankov 			outflags &= ~MMAN_spc;
706*260e9a87SYuri Pankov 			print_word(",");
707*260e9a87SYuri Pankov 		}
708*260e9a87SYuri Pankov 		if (n->next->next == NULL)
709*260e9a87SYuri Pankov 			print_word("and");
710*260e9a87SYuri Pankov 	}
711*260e9a87SYuri Pankov 
712*260e9a87SYuri Pankov 	if (nchild > 1)
713*260e9a87SYuri Pankov 		print_word("utilities exit\\~0");
714*260e9a87SYuri Pankov 	else
715*260e9a87SYuri Pankov 		print_word("utility exits\\~0");
716*260e9a87SYuri Pankov 
717*260e9a87SYuri Pankov 	print_word("on success, and\\~>0 if an error occurs.");
718*260e9a87SYuri Pankov 	outflags |= MMAN_nl;
719*260e9a87SYuri Pankov 	return(0);
720*260e9a87SYuri Pankov }
721*260e9a87SYuri Pankov 
722698f87a4SGarrett D'Amore static void
post_font(DECL_ARGS)723698f87a4SGarrett D'Amore post_font(DECL_ARGS)
724698f87a4SGarrett D'Amore {
725698f87a4SGarrett D'Amore 
726698f87a4SGarrett D'Amore 	font_pop();
727698f87a4SGarrett D'Amore }
728698f87a4SGarrett D'Amore 
72995c635efSGarrett D'Amore static void
post_percent(DECL_ARGS)73095c635efSGarrett D'Amore post_percent(DECL_ARGS)
73195c635efSGarrett D'Amore {
73295c635efSGarrett D'Amore 
733698f87a4SGarrett D'Amore 	if (pre_em == manacts[n->tok].pre)
734698f87a4SGarrett D'Amore 		font_pop();
735698f87a4SGarrett D'Amore 	if (n->next) {
736698f87a4SGarrett D'Amore 		print_word(",");
737698f87a4SGarrett D'Amore 		if (n->prev &&	n->prev->tok == n->tok &&
738698f87a4SGarrett D'Amore 				n->next->tok == n->tok)
739698f87a4SGarrett D'Amore 			print_word("and");
740698f87a4SGarrett D'Amore 	} else {
741698f87a4SGarrett D'Amore 		print_word(".");
742698f87a4SGarrett D'Amore 		outflags |= MMAN_nl;
74395c635efSGarrett D'Amore 	}
74495c635efSGarrett D'Amore }
74595c635efSGarrett D'Amore 
746698f87a4SGarrett D'Amore static int
pre__t(DECL_ARGS)747698f87a4SGarrett D'Amore pre__t(DECL_ARGS)
748698f87a4SGarrett D'Amore {
749698f87a4SGarrett D'Amore 
750698f87a4SGarrett D'Amore 	if (n->parent && MDOC_Rs == n->parent->tok &&
751698f87a4SGarrett D'Amore 	    n->parent->norm->Rs.quote_T) {
752698f87a4SGarrett D'Amore 		print_word("");
753698f87a4SGarrett D'Amore 		putchar('\"');
754698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
755698f87a4SGarrett D'Amore 	} else
756698f87a4SGarrett D'Amore 		font_push('I');
757698f87a4SGarrett D'Amore 	return(1);
758698f87a4SGarrett D'Amore }
759698f87a4SGarrett D'Amore 
760698f87a4SGarrett D'Amore static void
post__t(DECL_ARGS)761698f87a4SGarrett D'Amore post__t(DECL_ARGS)
762698f87a4SGarrett D'Amore {
763698f87a4SGarrett D'Amore 
764698f87a4SGarrett D'Amore 	if (n->parent && MDOC_Rs == n->parent->tok &&
765698f87a4SGarrett D'Amore 	    n->parent->norm->Rs.quote_T) {
766698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
767698f87a4SGarrett D'Amore 		print_word("");
768698f87a4SGarrett D'Amore 		putchar('\"');
769698f87a4SGarrett D'Amore 	} else
770698f87a4SGarrett D'Amore 		font_pop();
771698f87a4SGarrett D'Amore 	post_percent(meta, n);
772698f87a4SGarrett D'Amore }
773698f87a4SGarrett D'Amore 
77495c635efSGarrett D'Amore /*
77595c635efSGarrett D'Amore  * Print before a section header.
77695c635efSGarrett D'Amore  */
77795c635efSGarrett D'Amore static int
pre_sect(DECL_ARGS)77895c635efSGarrett D'Amore pre_sect(DECL_ARGS)
77995c635efSGarrett D'Amore {
78095c635efSGarrett D'Amore 
781698f87a4SGarrett D'Amore 	if (MDOC_HEAD == n->type) {
782698f87a4SGarrett D'Amore 		outflags |= MMAN_sp;
783698f87a4SGarrett D'Amore 		print_block(manacts[n->tok].prefix, 0);
784698f87a4SGarrett D'Amore 		print_word("");
785698f87a4SGarrett D'Amore 		putchar('\"');
786698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
787698f87a4SGarrett D'Amore 	}
78895c635efSGarrett D'Amore 	return(1);
78995c635efSGarrett D'Amore }
79095c635efSGarrett D'Amore 
79195c635efSGarrett D'Amore /*
79295c635efSGarrett D'Amore  * Print subsequent a section header.
79395c635efSGarrett D'Amore  */
79495c635efSGarrett D'Amore static void
post_sect(DECL_ARGS)79595c635efSGarrett D'Amore post_sect(DECL_ARGS)
79695c635efSGarrett D'Amore {
79795c635efSGarrett D'Amore 
79895c635efSGarrett D'Amore 	if (MDOC_HEAD != n->type)
79995c635efSGarrett D'Amore 		return;
800698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
801698f87a4SGarrett D'Amore 	print_word("");
802698f87a4SGarrett D'Amore 	putchar('\"');
803698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
804698f87a4SGarrett D'Amore 	if (MDOC_Sh == n->tok && SEC_AUTHORS == n->sec)
805698f87a4SGarrett D'Amore 		outflags &= ~(MMAN_An_split | MMAN_An_nosplit);
806698f87a4SGarrett D'Amore }
807698f87a4SGarrett D'Amore 
808698f87a4SGarrett D'Amore /* See mdoc_term.c, synopsis_pre() for comments. */
809698f87a4SGarrett D'Amore static void
pre_syn(const struct mdoc_node * n)810698f87a4SGarrett D'Amore pre_syn(const struct mdoc_node *n)
811698f87a4SGarrett D'Amore {
812698f87a4SGarrett D'Amore 
813698f87a4SGarrett D'Amore 	if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
814698f87a4SGarrett D'Amore 		return;
815698f87a4SGarrett D'Amore 
816698f87a4SGarrett D'Amore 	if (n->prev->tok == n->tok &&
817698f87a4SGarrett D'Amore 	    MDOC_Ft != n->tok &&
818698f87a4SGarrett D'Amore 	    MDOC_Fo != n->tok &&
819698f87a4SGarrett D'Amore 	    MDOC_Fn != n->tok) {
820698f87a4SGarrett D'Amore 		outflags |= MMAN_br;
821698f87a4SGarrett D'Amore 		return;
822698f87a4SGarrett D'Amore 	}
823698f87a4SGarrett D'Amore 
824698f87a4SGarrett D'Amore 	switch (n->prev->tok) {
825*260e9a87SYuri Pankov 	case MDOC_Fd:
826698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
827*260e9a87SYuri Pankov 	case MDOC_Fn:
828698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
829*260e9a87SYuri Pankov 	case MDOC_Fo:
830698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
831*260e9a87SYuri Pankov 	case MDOC_In:
832698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
833*260e9a87SYuri Pankov 	case MDOC_Vt:
834698f87a4SGarrett D'Amore 		outflags |= MMAN_sp;
835698f87a4SGarrett D'Amore 		break;
836*260e9a87SYuri Pankov 	case MDOC_Ft:
837698f87a4SGarrett D'Amore 		if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
838698f87a4SGarrett D'Amore 			outflags |= MMAN_sp;
839698f87a4SGarrett D'Amore 			break;
840698f87a4SGarrett D'Amore 		}
841698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
842698f87a4SGarrett D'Amore 	default:
843698f87a4SGarrett D'Amore 		outflags |= MMAN_br;
844698f87a4SGarrett D'Amore 		break;
845698f87a4SGarrett D'Amore 	}
846698f87a4SGarrett D'Amore }
847698f87a4SGarrett D'Amore 
848698f87a4SGarrett D'Amore static int
pre_an(DECL_ARGS)849698f87a4SGarrett D'Amore pre_an(DECL_ARGS)
850698f87a4SGarrett D'Amore {
851698f87a4SGarrett D'Amore 
852698f87a4SGarrett D'Amore 	switch (n->norm->An.auth) {
853*260e9a87SYuri Pankov 	case AUTH_split:
854698f87a4SGarrett D'Amore 		outflags &= ~MMAN_An_nosplit;
855698f87a4SGarrett D'Amore 		outflags |= MMAN_An_split;
856698f87a4SGarrett D'Amore 		return(0);
857*260e9a87SYuri Pankov 	case AUTH_nosplit:
858698f87a4SGarrett D'Amore 		outflags &= ~MMAN_An_split;
859698f87a4SGarrett D'Amore 		outflags |= MMAN_An_nosplit;
860698f87a4SGarrett D'Amore 		return(0);
861698f87a4SGarrett D'Amore 	default:
862698f87a4SGarrett D'Amore 		if (MMAN_An_split & outflags)
863698f87a4SGarrett D'Amore 			outflags |= MMAN_br;
864698f87a4SGarrett D'Amore 		else if (SEC_AUTHORS == n->sec &&
865698f87a4SGarrett D'Amore 		    ! (MMAN_An_nosplit & outflags))
866698f87a4SGarrett D'Amore 			outflags |= MMAN_An_split;
867698f87a4SGarrett D'Amore 		return(1);
868698f87a4SGarrett D'Amore 	}
86995c635efSGarrett D'Amore }
87095c635efSGarrett D'Amore 
87195c635efSGarrett D'Amore static int
pre_ap(DECL_ARGS)87295c635efSGarrett D'Amore pre_ap(DECL_ARGS)
87395c635efSGarrett D'Amore {
87495c635efSGarrett D'Amore 
875698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
876698f87a4SGarrett D'Amore 	print_word("'");
877698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
87895c635efSGarrett D'Amore 	return(0);
87995c635efSGarrett D'Amore }
88095c635efSGarrett D'Amore 
88195c635efSGarrett D'Amore static int
pre_aq(DECL_ARGS)882*260e9a87SYuri Pankov pre_aq(DECL_ARGS)
883*260e9a87SYuri Pankov {
884*260e9a87SYuri Pankov 
885*260e9a87SYuri Pankov 	print_word(n->nchild == 1 &&
886*260e9a87SYuri Pankov 	    n->child->tok == MDOC_Mt ?  "<" : "\\(la");
887*260e9a87SYuri Pankov 	outflags &= ~MMAN_spc;
888*260e9a87SYuri Pankov 	return(1);
889*260e9a87SYuri Pankov }
890*260e9a87SYuri Pankov 
891*260e9a87SYuri Pankov static void
post_aq(DECL_ARGS)892*260e9a87SYuri Pankov post_aq(DECL_ARGS)
893*260e9a87SYuri Pankov {
894*260e9a87SYuri Pankov 
895*260e9a87SYuri Pankov 	outflags &= ~(MMAN_spc | MMAN_nl);
896*260e9a87SYuri Pankov 	print_word(n->nchild == 1 &&
897*260e9a87SYuri Pankov 	    n->child->tok == MDOC_Mt ?  ">" : "\\(ra");
898*260e9a87SYuri Pankov }
899*260e9a87SYuri Pankov 
900*260e9a87SYuri Pankov static int
pre_bd(DECL_ARGS)90195c635efSGarrett D'Amore pre_bd(DECL_ARGS)
90295c635efSGarrett D'Amore {
90395c635efSGarrett D'Amore 
904698f87a4SGarrett D'Amore 	outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br);
905698f87a4SGarrett D'Amore 
90695c635efSGarrett D'Amore 	if (DISP_unfilled == n->norm->Bd.type ||
907698f87a4SGarrett D'Amore 	    DISP_literal  == n->norm->Bd.type)
908698f87a4SGarrett D'Amore 		print_line(".nf", 0);
909698f87a4SGarrett D'Amore 	if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
910698f87a4SGarrett D'Amore 		outflags |= MMAN_sp;
911*260e9a87SYuri Pankov 	print_offs(n->norm->Bd.offs, 1);
91295c635efSGarrett D'Amore 	return(1);
91395c635efSGarrett D'Amore }
91495c635efSGarrett D'Amore 
91595c635efSGarrett D'Amore static void
post_bd(DECL_ARGS)91695c635efSGarrett D'Amore post_bd(DECL_ARGS)
91795c635efSGarrett D'Amore {
91895c635efSGarrett D'Amore 
919698f87a4SGarrett D'Amore 	/* Close out this display. */
920698f87a4SGarrett D'Amore 	print_line(".RE", MMAN_nl);
92195c635efSGarrett D'Amore 	if (DISP_unfilled == n->norm->Bd.type ||
922698f87a4SGarrett D'Amore 	    DISP_literal  == n->norm->Bd.type)
923698f87a4SGarrett D'Amore 		print_line(".fi", MMAN_nl);
924698f87a4SGarrett D'Amore 
925698f87a4SGarrett D'Amore 	/* Maybe we are inside an enclosing list? */
926698f87a4SGarrett D'Amore 	if (NULL != n->parent->next)
927698f87a4SGarrett D'Amore 		mid_it();
92895c635efSGarrett D'Amore }
929698f87a4SGarrett D'Amore 
930698f87a4SGarrett D'Amore static int
pre_bf(DECL_ARGS)931698f87a4SGarrett D'Amore pre_bf(DECL_ARGS)
932698f87a4SGarrett D'Amore {
933698f87a4SGarrett D'Amore 
934698f87a4SGarrett D'Amore 	switch (n->type) {
935*260e9a87SYuri Pankov 	case MDOC_BLOCK:
936698f87a4SGarrett D'Amore 		return(1);
937*260e9a87SYuri Pankov 	case MDOC_BODY:
938698f87a4SGarrett D'Amore 		break;
939698f87a4SGarrett D'Amore 	default:
940698f87a4SGarrett D'Amore 		return(0);
941698f87a4SGarrett D'Amore 	}
942698f87a4SGarrett D'Amore 	switch (n->norm->Bf.font) {
943*260e9a87SYuri Pankov 	case FONT_Em:
944698f87a4SGarrett D'Amore 		font_push('I');
945698f87a4SGarrett D'Amore 		break;
946*260e9a87SYuri Pankov 	case FONT_Sy:
947698f87a4SGarrett D'Amore 		font_push('B');
948698f87a4SGarrett D'Amore 		break;
949698f87a4SGarrett D'Amore 	default:
950698f87a4SGarrett D'Amore 		font_push('R');
951698f87a4SGarrett D'Amore 		break;
952698f87a4SGarrett D'Amore 	}
953698f87a4SGarrett D'Amore 	return(1);
954698f87a4SGarrett D'Amore }
955698f87a4SGarrett D'Amore 
956698f87a4SGarrett D'Amore static void
post_bf(DECL_ARGS)957698f87a4SGarrett D'Amore post_bf(DECL_ARGS)
958698f87a4SGarrett D'Amore {
959698f87a4SGarrett D'Amore 
960698f87a4SGarrett D'Amore 	if (MDOC_BODY == n->type)
961698f87a4SGarrett D'Amore 		font_pop();
962698f87a4SGarrett D'Amore }
963698f87a4SGarrett D'Amore 
964698f87a4SGarrett D'Amore static int
pre_bk(DECL_ARGS)965698f87a4SGarrett D'Amore pre_bk(DECL_ARGS)
966698f87a4SGarrett D'Amore {
967698f87a4SGarrett D'Amore 
968698f87a4SGarrett D'Amore 	switch (n->type) {
969*260e9a87SYuri Pankov 	case MDOC_BLOCK:
970698f87a4SGarrett D'Amore 		return(1);
971*260e9a87SYuri Pankov 	case MDOC_BODY:
972698f87a4SGarrett D'Amore 		outflags |= MMAN_Bk;
973698f87a4SGarrett D'Amore 		return(1);
974698f87a4SGarrett D'Amore 	default:
975698f87a4SGarrett D'Amore 		return(0);
976698f87a4SGarrett D'Amore 	}
977698f87a4SGarrett D'Amore }
978698f87a4SGarrett D'Amore 
979698f87a4SGarrett D'Amore static void
post_bk(DECL_ARGS)980698f87a4SGarrett D'Amore post_bk(DECL_ARGS)
981698f87a4SGarrett D'Amore {
982698f87a4SGarrett D'Amore 
983698f87a4SGarrett D'Amore 	if (MDOC_BODY == n->type)
984698f87a4SGarrett D'Amore 		outflags &= ~MMAN_Bk;
985698f87a4SGarrett D'Amore }
986698f87a4SGarrett D'Amore 
987698f87a4SGarrett D'Amore static int
pre_bl(DECL_ARGS)988698f87a4SGarrett D'Amore pre_bl(DECL_ARGS)
989698f87a4SGarrett D'Amore {
990698f87a4SGarrett D'Amore 	size_t		 icol;
991698f87a4SGarrett D'Amore 
992698f87a4SGarrett D'Amore 	/*
993698f87a4SGarrett D'Amore 	 * print_offs() will increase the -offset to account for
994698f87a4SGarrett D'Amore 	 * a possible enclosing .It, but any enclosed .It blocks
995698f87a4SGarrett D'Amore 	 * just nest and do not add up their indentation.
996698f87a4SGarrett D'Amore 	 */
997698f87a4SGarrett D'Amore 	if (n->norm->Bl.offs) {
998*260e9a87SYuri Pankov 		print_offs(n->norm->Bl.offs, 0);
999698f87a4SGarrett D'Amore 		Bl_stack[Bl_stack_len++] = 0;
1000698f87a4SGarrett D'Amore 	}
1001698f87a4SGarrett D'Amore 
1002698f87a4SGarrett D'Amore 	switch (n->norm->Bl.type) {
1003*260e9a87SYuri Pankov 	case LIST_enum:
1004698f87a4SGarrett D'Amore 		n->norm->Bl.count = 0;
1005698f87a4SGarrett D'Amore 		return(1);
1006*260e9a87SYuri Pankov 	case LIST_column:
1007698f87a4SGarrett D'Amore 		break;
1008698f87a4SGarrett D'Amore 	default:
1009698f87a4SGarrett D'Amore 		return(1);
1010698f87a4SGarrett D'Amore 	}
1011698f87a4SGarrett D'Amore 
1012*260e9a87SYuri Pankov 	if (n->nchild) {
1013698f87a4SGarrett D'Amore 		print_line(".TS", MMAN_nl);
1014698f87a4SGarrett D'Amore 		for (icol = 0; icol < n->norm->Bl.ncols; icol++)
1015698f87a4SGarrett D'Amore 			print_word("l");
1016698f87a4SGarrett D'Amore 		print_word(".");
1017*260e9a87SYuri Pankov 	}
1018698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
1019698f87a4SGarrett D'Amore 	return(1);
1020698f87a4SGarrett D'Amore }
1021698f87a4SGarrett D'Amore 
1022698f87a4SGarrett D'Amore static void
post_bl(DECL_ARGS)1023698f87a4SGarrett D'Amore post_bl(DECL_ARGS)
1024698f87a4SGarrett D'Amore {
1025698f87a4SGarrett D'Amore 
1026698f87a4SGarrett D'Amore 	switch (n->norm->Bl.type) {
1027*260e9a87SYuri Pankov 	case LIST_column:
1028*260e9a87SYuri Pankov 		if (n->nchild)
1029698f87a4SGarrett D'Amore 			print_line(".TE", 0);
1030698f87a4SGarrett D'Amore 		break;
1031*260e9a87SYuri Pankov 	case LIST_enum:
1032698f87a4SGarrett D'Amore 		n->norm->Bl.count = 0;
1033698f87a4SGarrett D'Amore 		break;
1034698f87a4SGarrett D'Amore 	default:
1035698f87a4SGarrett D'Amore 		break;
1036698f87a4SGarrett D'Amore 	}
1037698f87a4SGarrett D'Amore 
1038698f87a4SGarrett D'Amore 	if (n->norm->Bl.offs) {
1039698f87a4SGarrett D'Amore 		print_line(".RE", MMAN_nl);
1040698f87a4SGarrett D'Amore 		assert(Bl_stack_len);
1041698f87a4SGarrett D'Amore 		Bl_stack_len--;
1042698f87a4SGarrett D'Amore 		assert(0 == Bl_stack[Bl_stack_len]);
1043698f87a4SGarrett D'Amore 	} else {
1044698f87a4SGarrett D'Amore 		outflags |= MMAN_PP | MMAN_nl;
1045698f87a4SGarrett D'Amore 		outflags &= ~(MMAN_sp | MMAN_br);
1046698f87a4SGarrett D'Amore 	}
1047698f87a4SGarrett D'Amore 
1048698f87a4SGarrett D'Amore 	/* Maybe we are inside an enclosing list? */
1049698f87a4SGarrett D'Amore 	if (NULL != n->parent->next)
1050698f87a4SGarrett D'Amore 		mid_it();
1051698f87a4SGarrett D'Amore 
105295c635efSGarrett D'Amore }
105395c635efSGarrett D'Amore 
105495c635efSGarrett D'Amore static int
pre_br(DECL_ARGS)105595c635efSGarrett D'Amore pre_br(DECL_ARGS)
105695c635efSGarrett D'Amore {
105795c635efSGarrett D'Amore 
1058698f87a4SGarrett D'Amore 	outflags |= MMAN_br;
105995c635efSGarrett D'Amore 	return(0);
106095c635efSGarrett D'Amore }
106195c635efSGarrett D'Amore 
106295c635efSGarrett D'Amore static int
pre_bx(DECL_ARGS)106395c635efSGarrett D'Amore pre_bx(DECL_ARGS)
106495c635efSGarrett D'Amore {
106595c635efSGarrett D'Amore 
106695c635efSGarrett D'Amore 	n = n->child;
106795c635efSGarrett D'Amore 	if (n) {
1068698f87a4SGarrett D'Amore 		print_word(n->string);
1069698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
107095c635efSGarrett D'Amore 		n = n->next;
107195c635efSGarrett D'Amore 	}
1072698f87a4SGarrett D'Amore 	print_word("BSD");
107395c635efSGarrett D'Amore 	if (NULL == n)
107495c635efSGarrett D'Amore 		return(0);
1075698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1076698f87a4SGarrett D'Amore 	print_word("-");
1077698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1078698f87a4SGarrett D'Amore 	print_word(n->string);
107995c635efSGarrett D'Amore 	return(0);
108095c635efSGarrett D'Amore }
108195c635efSGarrett D'Amore 
108295c635efSGarrett D'Amore static int
pre_dl(DECL_ARGS)108395c635efSGarrett D'Amore pre_dl(DECL_ARGS)
108495c635efSGarrett D'Amore {
108595c635efSGarrett D'Amore 
1086*260e9a87SYuri Pankov 	print_offs("6n", 0);
108795c635efSGarrett D'Amore 	return(1);
108895c635efSGarrett D'Amore }
108995c635efSGarrett D'Amore 
109095c635efSGarrett D'Amore static void
post_dl(DECL_ARGS)109195c635efSGarrett D'Amore post_dl(DECL_ARGS)
109295c635efSGarrett D'Amore {
109395c635efSGarrett D'Amore 
1094698f87a4SGarrett D'Amore 	print_line(".RE", MMAN_nl);
1095698f87a4SGarrett D'Amore 
1096698f87a4SGarrett D'Amore 	/* Maybe we are inside an enclosing list? */
1097698f87a4SGarrett D'Amore 	if (NULL != n->parent->next)
1098698f87a4SGarrett D'Amore 		mid_it();
1099698f87a4SGarrett D'Amore }
1100698f87a4SGarrett D'Amore 
1101698f87a4SGarrett D'Amore static int
pre_em(DECL_ARGS)1102698f87a4SGarrett D'Amore pre_em(DECL_ARGS)
1103698f87a4SGarrett D'Amore {
1104698f87a4SGarrett D'Amore 
1105698f87a4SGarrett D'Amore 	font_push('I');
1106698f87a4SGarrett D'Amore 	return(1);
1107698f87a4SGarrett D'Amore }
1108698f87a4SGarrett D'Amore 
1109*260e9a87SYuri Pankov static int
pre_en(DECL_ARGS)1110*260e9a87SYuri Pankov pre_en(DECL_ARGS)
1111*260e9a87SYuri Pankov {
1112*260e9a87SYuri Pankov 
1113*260e9a87SYuri Pankov 	if (NULL == n->norm->Es ||
1114*260e9a87SYuri Pankov 	    NULL == n->norm->Es->child)
1115*260e9a87SYuri Pankov 		return(1);
1116*260e9a87SYuri Pankov 
1117*260e9a87SYuri Pankov 	print_word(n->norm->Es->child->string);
1118*260e9a87SYuri Pankov 	outflags &= ~MMAN_spc;
1119*260e9a87SYuri Pankov 	return(1);
1120*260e9a87SYuri Pankov }
1121*260e9a87SYuri Pankov 
1122*260e9a87SYuri Pankov static void
post_en(DECL_ARGS)1123*260e9a87SYuri Pankov post_en(DECL_ARGS)
1124*260e9a87SYuri Pankov {
1125*260e9a87SYuri Pankov 
1126*260e9a87SYuri Pankov 	if (NULL == n->norm->Es ||
1127*260e9a87SYuri Pankov 	    NULL == n->norm->Es->child ||
1128*260e9a87SYuri Pankov 	    NULL == n->norm->Es->child->next)
1129*260e9a87SYuri Pankov 		return;
1130*260e9a87SYuri Pankov 
1131*260e9a87SYuri Pankov 	outflags &= ~MMAN_spc;
1132*260e9a87SYuri Pankov 	print_word(n->norm->Es->child->next->string);
1133*260e9a87SYuri Pankov 	return;
1134*260e9a87SYuri Pankov }
1135*260e9a87SYuri Pankov 
1136*260e9a87SYuri Pankov static int
pre_eo(DECL_ARGS)1137*260e9a87SYuri Pankov pre_eo(DECL_ARGS)
1138*260e9a87SYuri Pankov {
1139*260e9a87SYuri Pankov 
1140*260e9a87SYuri Pankov 	if (n->end == ENDBODY_NOT &&
1141*260e9a87SYuri Pankov 	    n->parent->head->child == NULL &&
1142*260e9a87SYuri Pankov 	    n->child != NULL &&
1143*260e9a87SYuri Pankov 	    n->child->end != ENDBODY_NOT)
1144*260e9a87SYuri Pankov 		print_word("\\&");
1145*260e9a87SYuri Pankov 	else if (n->end != ENDBODY_NOT ? n->child != NULL :
1146*260e9a87SYuri Pankov 	    n->parent->head->child != NULL && (n->child != NULL ||
1147*260e9a87SYuri Pankov 	    (n->parent->tail != NULL && n->parent->tail->child != NULL)))
1148*260e9a87SYuri Pankov 		outflags &= ~(MMAN_spc | MMAN_nl);
1149*260e9a87SYuri Pankov 	return(1);
1150*260e9a87SYuri Pankov }
1151*260e9a87SYuri Pankov 
1152698f87a4SGarrett D'Amore static void
post_eo(DECL_ARGS)1153698f87a4SGarrett D'Amore post_eo(DECL_ARGS)
1154698f87a4SGarrett D'Amore {
1155*260e9a87SYuri Pankov 	int	 body, tail;
1156698f87a4SGarrett D'Amore 
1157*260e9a87SYuri Pankov 	if (n->end != ENDBODY_NOT) {
1158*260e9a87SYuri Pankov 		outflags |= MMAN_spc;
1159*260e9a87SYuri Pankov 		return;
1160*260e9a87SYuri Pankov 	}
1161*260e9a87SYuri Pankov 
1162*260e9a87SYuri Pankov 	body = n->child != NULL || n->parent->head->child != NULL;
1163*260e9a87SYuri Pankov 	tail = n->parent->tail != NULL && n->parent->tail->child != NULL;
1164*260e9a87SYuri Pankov 
1165*260e9a87SYuri Pankov 	if (body && tail)
1166698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1167*260e9a87SYuri Pankov 	else if ( ! (body || tail))
1168*260e9a87SYuri Pankov 		print_word("\\&");
1169*260e9a87SYuri Pankov 	else if ( ! tail)
1170*260e9a87SYuri Pankov 		outflags |= MMAN_spc;
1171698f87a4SGarrett D'Amore }
1172698f87a4SGarrett D'Amore 
1173698f87a4SGarrett D'Amore static int
pre_fa(DECL_ARGS)1174698f87a4SGarrett D'Amore pre_fa(DECL_ARGS)
1175698f87a4SGarrett D'Amore {
1176698f87a4SGarrett D'Amore 	int	 am_Fa;
1177698f87a4SGarrett D'Amore 
1178698f87a4SGarrett D'Amore 	am_Fa = MDOC_Fa == n->tok;
1179698f87a4SGarrett D'Amore 
1180698f87a4SGarrett D'Amore 	if (am_Fa)
1181698f87a4SGarrett D'Amore 		n = n->child;
1182698f87a4SGarrett D'Amore 
1183698f87a4SGarrett D'Amore 	while (NULL != n) {
1184698f87a4SGarrett D'Amore 		font_push('I');
1185698f87a4SGarrett D'Amore 		if (am_Fa || MDOC_SYNPRETTY & n->flags)
1186698f87a4SGarrett D'Amore 			outflags |= MMAN_nbrword;
1187698f87a4SGarrett D'Amore 		print_node(meta, n);
1188698f87a4SGarrett D'Amore 		font_pop();
1189698f87a4SGarrett D'Amore 		if (NULL != (n = n->next))
1190698f87a4SGarrett D'Amore 			print_word(",");
1191698f87a4SGarrett D'Amore 	}
1192698f87a4SGarrett D'Amore 	return(0);
1193698f87a4SGarrett D'Amore }
1194698f87a4SGarrett D'Amore 
1195698f87a4SGarrett D'Amore static void
post_fa(DECL_ARGS)1196698f87a4SGarrett D'Amore post_fa(DECL_ARGS)
1197698f87a4SGarrett D'Amore {
1198698f87a4SGarrett D'Amore 
1199698f87a4SGarrett D'Amore 	if (NULL != n->next && MDOC_Fa == n->next->tok)
1200698f87a4SGarrett D'Amore 		print_word(",");
1201698f87a4SGarrett D'Amore }
1202698f87a4SGarrett D'Amore 
1203698f87a4SGarrett D'Amore static int
pre_fd(DECL_ARGS)1204698f87a4SGarrett D'Amore pre_fd(DECL_ARGS)
1205698f87a4SGarrett D'Amore {
1206698f87a4SGarrett D'Amore 
1207698f87a4SGarrett D'Amore 	pre_syn(n);
1208698f87a4SGarrett D'Amore 	font_push('B');
1209698f87a4SGarrett D'Amore 	return(1);
1210698f87a4SGarrett D'Amore }
1211698f87a4SGarrett D'Amore 
1212698f87a4SGarrett D'Amore static void
post_fd(DECL_ARGS)1213698f87a4SGarrett D'Amore post_fd(DECL_ARGS)
1214698f87a4SGarrett D'Amore {
1215698f87a4SGarrett D'Amore 
1216698f87a4SGarrett D'Amore 	font_pop();
1217698f87a4SGarrett D'Amore 	outflags |= MMAN_br;
1218698f87a4SGarrett D'Amore }
1219698f87a4SGarrett D'Amore 
1220698f87a4SGarrett D'Amore static int
pre_fl(DECL_ARGS)1221698f87a4SGarrett D'Amore pre_fl(DECL_ARGS)
1222698f87a4SGarrett D'Amore {
1223698f87a4SGarrett D'Amore 
1224698f87a4SGarrett D'Amore 	font_push('B');
1225698f87a4SGarrett D'Amore 	print_word("\\-");
1226*260e9a87SYuri Pankov 	if (n->nchild)
1227698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1228698f87a4SGarrett D'Amore 	return(1);
1229698f87a4SGarrett D'Amore }
1230698f87a4SGarrett D'Amore 
1231698f87a4SGarrett D'Amore static void
post_fl(DECL_ARGS)1232698f87a4SGarrett D'Amore post_fl(DECL_ARGS)
1233698f87a4SGarrett D'Amore {
1234698f87a4SGarrett D'Amore 
1235698f87a4SGarrett D'Amore 	font_pop();
1236*260e9a87SYuri Pankov 	if ( ! (n->nchild ||
1237*260e9a87SYuri Pankov 	    n->next == NULL ||
1238*260e9a87SYuri Pankov 	    n->next->type == MDOC_TEXT ||
1239*260e9a87SYuri Pankov 	    n->next->flags & MDOC_LINE))
1240698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1241698f87a4SGarrett D'Amore }
1242698f87a4SGarrett D'Amore 
1243698f87a4SGarrett D'Amore static int
pre_fn(DECL_ARGS)1244698f87a4SGarrett D'Amore pre_fn(DECL_ARGS)
1245698f87a4SGarrett D'Amore {
1246698f87a4SGarrett D'Amore 
1247698f87a4SGarrett D'Amore 	pre_syn(n);
1248698f87a4SGarrett D'Amore 
1249698f87a4SGarrett D'Amore 	n = n->child;
1250698f87a4SGarrett D'Amore 	if (NULL == n)
1251698f87a4SGarrett D'Amore 		return(0);
1252698f87a4SGarrett D'Amore 
1253698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags)
1254698f87a4SGarrett D'Amore 		print_block(".HP 4n", MMAN_nl);
1255698f87a4SGarrett D'Amore 
1256698f87a4SGarrett D'Amore 	font_push('B');
1257698f87a4SGarrett D'Amore 	print_node(meta, n);
1258698f87a4SGarrett D'Amore 	font_pop();
1259698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1260698f87a4SGarrett D'Amore 	print_word("(");
1261698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1262698f87a4SGarrett D'Amore 
1263698f87a4SGarrett D'Amore 	n = n->next;
1264698f87a4SGarrett D'Amore 	if (NULL != n)
1265698f87a4SGarrett D'Amore 		pre_fa(meta, n);
1266698f87a4SGarrett D'Amore 	return(0);
1267698f87a4SGarrett D'Amore }
1268698f87a4SGarrett D'Amore 
1269698f87a4SGarrett D'Amore static void
post_fn(DECL_ARGS)1270698f87a4SGarrett D'Amore post_fn(DECL_ARGS)
1271698f87a4SGarrett D'Amore {
1272698f87a4SGarrett D'Amore 
1273698f87a4SGarrett D'Amore 	print_word(")");
1274698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags) {
1275698f87a4SGarrett D'Amore 		print_word(";");
1276698f87a4SGarrett D'Amore 		outflags |= MMAN_PP;
1277698f87a4SGarrett D'Amore 	}
1278698f87a4SGarrett D'Amore }
1279698f87a4SGarrett D'Amore 
1280698f87a4SGarrett D'Amore static int
pre_fo(DECL_ARGS)1281698f87a4SGarrett D'Amore pre_fo(DECL_ARGS)
1282698f87a4SGarrett D'Amore {
1283698f87a4SGarrett D'Amore 
1284698f87a4SGarrett D'Amore 	switch (n->type) {
1285*260e9a87SYuri Pankov 	case MDOC_BLOCK:
1286698f87a4SGarrett D'Amore 		pre_syn(n);
1287698f87a4SGarrett D'Amore 		break;
1288*260e9a87SYuri Pankov 	case MDOC_HEAD:
1289*260e9a87SYuri Pankov 		if (n->child == NULL)
1290*260e9a87SYuri Pankov 			return(0);
1291698f87a4SGarrett D'Amore 		if (MDOC_SYNPRETTY & n->flags)
1292698f87a4SGarrett D'Amore 			print_block(".HP 4n", MMAN_nl);
1293698f87a4SGarrett D'Amore 		font_push('B');
1294698f87a4SGarrett D'Amore 		break;
1295*260e9a87SYuri Pankov 	case MDOC_BODY:
1296*260e9a87SYuri Pankov 		outflags &= ~(MMAN_spc | MMAN_nl);
1297698f87a4SGarrett D'Amore 		print_word("(");
1298698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1299698f87a4SGarrett D'Amore 		break;
1300698f87a4SGarrett D'Amore 	default:
1301698f87a4SGarrett D'Amore 		break;
1302698f87a4SGarrett D'Amore 	}
1303698f87a4SGarrett D'Amore 	return(1);
1304698f87a4SGarrett D'Amore }
1305698f87a4SGarrett D'Amore 
1306698f87a4SGarrett D'Amore static void
post_fo(DECL_ARGS)1307698f87a4SGarrett D'Amore post_fo(DECL_ARGS)
1308698f87a4SGarrett D'Amore {
1309698f87a4SGarrett D'Amore 
1310698f87a4SGarrett D'Amore 	switch (n->type) {
1311*260e9a87SYuri Pankov 	case MDOC_HEAD:
1312*260e9a87SYuri Pankov 		if (n->child != NULL)
1313698f87a4SGarrett D'Amore 			font_pop();
1314698f87a4SGarrett D'Amore 		break;
1315*260e9a87SYuri Pankov 	case MDOC_BODY:
1316698f87a4SGarrett D'Amore 		post_fn(meta, n);
1317698f87a4SGarrett D'Amore 		break;
1318698f87a4SGarrett D'Amore 	default:
1319698f87a4SGarrett D'Amore 		break;
1320698f87a4SGarrett D'Amore 	}
1321698f87a4SGarrett D'Amore }
1322698f87a4SGarrett D'Amore 
1323698f87a4SGarrett D'Amore static int
pre_ft(DECL_ARGS)1324698f87a4SGarrett D'Amore pre_ft(DECL_ARGS)
1325698f87a4SGarrett D'Amore {
1326698f87a4SGarrett D'Amore 
1327698f87a4SGarrett D'Amore 	pre_syn(n);
1328698f87a4SGarrett D'Amore 	font_push('I');
1329698f87a4SGarrett D'Amore 	return(1);
1330698f87a4SGarrett D'Amore }
1331698f87a4SGarrett D'Amore 
1332698f87a4SGarrett D'Amore static int
pre_in(DECL_ARGS)1333698f87a4SGarrett D'Amore pre_in(DECL_ARGS)
1334698f87a4SGarrett D'Amore {
1335698f87a4SGarrett D'Amore 
1336698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags) {
1337698f87a4SGarrett D'Amore 		pre_syn(n);
1338698f87a4SGarrett D'Amore 		font_push('B');
1339698f87a4SGarrett D'Amore 		print_word("#include <");
1340698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1341698f87a4SGarrett D'Amore 	} else {
1342698f87a4SGarrett D'Amore 		print_word("<");
1343698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1344698f87a4SGarrett D'Amore 		font_push('I');
1345698f87a4SGarrett D'Amore 	}
1346698f87a4SGarrett D'Amore 	return(1);
1347698f87a4SGarrett D'Amore }
1348698f87a4SGarrett D'Amore 
1349698f87a4SGarrett D'Amore static void
post_in(DECL_ARGS)1350698f87a4SGarrett D'Amore post_in(DECL_ARGS)
1351698f87a4SGarrett D'Amore {
1352698f87a4SGarrett D'Amore 
1353698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags) {
1354698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1355698f87a4SGarrett D'Amore 		print_word(">");
1356698f87a4SGarrett D'Amore 		font_pop();
1357698f87a4SGarrett D'Amore 		outflags |= MMAN_br;
1358698f87a4SGarrett D'Amore 	} else {
1359698f87a4SGarrett D'Amore 		font_pop();
1360698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
1361698f87a4SGarrett D'Amore 		print_word(">");
1362698f87a4SGarrett D'Amore 	}
136395c635efSGarrett D'Amore }
136495c635efSGarrett D'Amore 
136595c635efSGarrett D'Amore static int
pre_it(DECL_ARGS)136695c635efSGarrett D'Amore pre_it(DECL_ARGS)
136795c635efSGarrett D'Amore {
136895c635efSGarrett D'Amore 	const struct mdoc_node *bln;
136995c635efSGarrett D'Amore 
1370698f87a4SGarrett D'Amore 	switch (n->type) {
1371*260e9a87SYuri Pankov 	case MDOC_HEAD:
1372698f87a4SGarrett D'Amore 		outflags |= MMAN_PP | MMAN_nl;
1373698f87a4SGarrett D'Amore 		bln = n->parent->parent;
1374698f87a4SGarrett D'Amore 		if (0 == bln->norm->Bl.comp ||
1375698f87a4SGarrett D'Amore 		    (NULL == n->parent->prev &&
1376698f87a4SGarrett D'Amore 		     NULL == bln->parent->prev))
1377698f87a4SGarrett D'Amore 			outflags |= MMAN_sp;
1378698f87a4SGarrett D'Amore 		outflags &= ~MMAN_br;
137995c635efSGarrett D'Amore 		switch (bln->norm->Bl.type) {
1380*260e9a87SYuri Pankov 		case LIST_item:
1381698f87a4SGarrett D'Amore 			return(0);
1382*260e9a87SYuri Pankov 		case LIST_inset:
1383698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1384*260e9a87SYuri Pankov 		case LIST_diag:
1385698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1386*260e9a87SYuri Pankov 		case LIST_ohang:
1387698f87a4SGarrett D'Amore 			if (bln->norm->Bl.type == LIST_diag)
1388698f87a4SGarrett D'Amore 				print_line(".B \"", 0);
1389698f87a4SGarrett D'Amore 			else
1390698f87a4SGarrett D'Amore 				print_line(".R \"", 0);
1391698f87a4SGarrett D'Amore 			outflags &= ~MMAN_spc;
1392698f87a4SGarrett D'Amore 			return(1);
1393*260e9a87SYuri Pankov 		case LIST_bullet:
1394698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1395*260e9a87SYuri Pankov 		case LIST_dash:
1396698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1397*260e9a87SYuri Pankov 		case LIST_hyphen:
1398*260e9a87SYuri Pankov 			print_width(&bln->norm->Bl, NULL);
1399698f87a4SGarrett D'Amore 			TPremain = 0;
1400698f87a4SGarrett D'Amore 			outflags |= MMAN_nl;
1401698f87a4SGarrett D'Amore 			font_push('B');
1402698f87a4SGarrett D'Amore 			if (LIST_bullet == bln->norm->Bl.type)
1403*260e9a87SYuri Pankov 				print_word("\\(bu");
1404698f87a4SGarrett D'Amore 			else
1405698f87a4SGarrett D'Amore 				print_word("-");
1406698f87a4SGarrett D'Amore 			font_pop();
1407*260e9a87SYuri Pankov 			outflags |= MMAN_nl;
1408*260e9a87SYuri Pankov 			return(0);
1409*260e9a87SYuri Pankov 		case LIST_enum:
1410*260e9a87SYuri Pankov 			print_width(&bln->norm->Bl, NULL);
1411698f87a4SGarrett D'Amore 			TPremain = 0;
1412698f87a4SGarrett D'Amore 			outflags |= MMAN_nl;
1413698f87a4SGarrett D'Amore 			print_count(&bln->norm->Bl.count);
1414*260e9a87SYuri Pankov 			outflags |= MMAN_nl;
1415*260e9a87SYuri Pankov 			return(0);
1416*260e9a87SYuri Pankov 		case LIST_hang:
1417*260e9a87SYuri Pankov 			print_width(&bln->norm->Bl, n->child);
1418698f87a4SGarrett D'Amore 			TPremain = 0;
1419*260e9a87SYuri Pankov 			outflags |= MMAN_nl;
1420*260e9a87SYuri Pankov 			return(1);
1421*260e9a87SYuri Pankov 		case LIST_tag:
1422*260e9a87SYuri Pankov 			print_width(&bln->norm->Bl, n->child);
1423698f87a4SGarrett D'Amore 			putchar('\n');
1424698f87a4SGarrett D'Amore 			outflags &= ~MMAN_spc;
1425698f87a4SGarrett D'Amore 			return(1);
1426698f87a4SGarrett D'Amore 		default:
1427698f87a4SGarrett D'Amore 			return(1);
1428698f87a4SGarrett D'Amore 		}
1429698f87a4SGarrett D'Amore 	default:
1430698f87a4SGarrett D'Amore 		break;
1431698f87a4SGarrett D'Amore 	}
1432698f87a4SGarrett D'Amore 	return(1);
1433698f87a4SGarrett D'Amore }
1434698f87a4SGarrett D'Amore 
1435698f87a4SGarrett D'Amore /*
1436698f87a4SGarrett D'Amore  * This function is called after closing out an indented block.
1437698f87a4SGarrett D'Amore  * If we are inside an enclosing list, restore its indentation.
1438698f87a4SGarrett D'Amore  */
1439698f87a4SGarrett D'Amore static void
mid_it(void)1440698f87a4SGarrett D'Amore mid_it(void)
1441698f87a4SGarrett D'Amore {
1442698f87a4SGarrett D'Amore 	char		 buf[24];
1443698f87a4SGarrett D'Amore 
1444698f87a4SGarrett D'Amore 	/* Nothing to do outside a list. */
1445698f87a4SGarrett D'Amore 	if (0 == Bl_stack_len || 0 == Bl_stack[Bl_stack_len - 1])
1446698f87a4SGarrett D'Amore 		return;
1447698f87a4SGarrett D'Amore 
1448698f87a4SGarrett D'Amore 	/* The indentation has already been set up. */
1449698f87a4SGarrett D'Amore 	if (Bl_stack_post[Bl_stack_len - 1])
1450698f87a4SGarrett D'Amore 		return;
1451698f87a4SGarrett D'Amore 
1452698f87a4SGarrett D'Amore 	/* Restore the indentation of the enclosing list. */
1453698f87a4SGarrett D'Amore 	print_line(".RS", MMAN_Bk_susp);
1454*260e9a87SYuri Pankov 	(void)snprintf(buf, sizeof(buf), "%dn",
1455*260e9a87SYuri Pankov 	    Bl_stack[Bl_stack_len - 1]);
1456698f87a4SGarrett D'Amore 	print_word(buf);
1457698f87a4SGarrett D'Amore 
1458698f87a4SGarrett D'Amore 	/* Remeber to close out this .RS block later. */
1459698f87a4SGarrett D'Amore 	Bl_stack_post[Bl_stack_len - 1] = 1;
1460698f87a4SGarrett D'Amore }
1461698f87a4SGarrett D'Amore 
1462698f87a4SGarrett D'Amore static void
post_it(DECL_ARGS)1463698f87a4SGarrett D'Amore post_it(DECL_ARGS)
1464698f87a4SGarrett D'Amore {
1465698f87a4SGarrett D'Amore 	const struct mdoc_node *bln;
1466698f87a4SGarrett D'Amore 
1467698f87a4SGarrett D'Amore 	bln = n->parent->parent;
1468698f87a4SGarrett D'Amore 
1469698f87a4SGarrett D'Amore 	switch (n->type) {
1470*260e9a87SYuri Pankov 	case MDOC_HEAD:
1471698f87a4SGarrett D'Amore 		switch (bln->norm->Bl.type) {
1472*260e9a87SYuri Pankov 		case LIST_diag:
1473698f87a4SGarrett D'Amore 			outflags &= ~MMAN_spc;
1474698f87a4SGarrett D'Amore 			print_word("\\ ");
1475698f87a4SGarrett D'Amore 			break;
1476*260e9a87SYuri Pankov 		case LIST_ohang:
1477698f87a4SGarrett D'Amore 			outflags |= MMAN_br;
147895c635efSGarrett D'Amore 			break;
147995c635efSGarrett D'Amore 		default:
148095c635efSGarrett D'Amore 			break;
148195c635efSGarrett D'Amore 		}
1482698f87a4SGarrett D'Amore 		break;
1483*260e9a87SYuri Pankov 	case MDOC_BODY:
1484698f87a4SGarrett D'Amore 		switch (bln->norm->Bl.type) {
1485*260e9a87SYuri Pankov 		case LIST_bullet:
1486698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1487*260e9a87SYuri Pankov 		case LIST_dash:
1488698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1489*260e9a87SYuri Pankov 		case LIST_hyphen:
1490698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1491*260e9a87SYuri Pankov 		case LIST_enum:
1492698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1493*260e9a87SYuri Pankov 		case LIST_hang:
1494698f87a4SGarrett D'Amore 			/* FALLTHROUGH */
1495*260e9a87SYuri Pankov 		case LIST_tag:
1496698f87a4SGarrett D'Amore 			assert(Bl_stack_len);
1497698f87a4SGarrett D'Amore 			Bl_stack[--Bl_stack_len] = 0;
1498698f87a4SGarrett D'Amore 
1499698f87a4SGarrett D'Amore 			/*
1500698f87a4SGarrett D'Amore 			 * Our indentation had to be restored
1501698f87a4SGarrett D'Amore 			 * after a child display or child list.
1502698f87a4SGarrett D'Amore 			 * Close out that indentation block now.
1503698f87a4SGarrett D'Amore 			 */
1504698f87a4SGarrett D'Amore 			if (Bl_stack_post[Bl_stack_len]) {
1505698f87a4SGarrett D'Amore 				print_line(".RE", MMAN_nl);
1506698f87a4SGarrett D'Amore 				Bl_stack_post[Bl_stack_len] = 0;
150795c635efSGarrett D'Amore 			}
1508698f87a4SGarrett D'Amore 			break;
1509*260e9a87SYuri Pankov 		case LIST_column:
1510698f87a4SGarrett D'Amore 			if (NULL != n->next) {
1511698f87a4SGarrett D'Amore 				putchar('\t');
1512698f87a4SGarrett D'Amore 				outflags &= ~MMAN_spc;
1513698f87a4SGarrett D'Amore 			}
1514698f87a4SGarrett D'Amore 			break;
1515698f87a4SGarrett D'Amore 		default:
1516698f87a4SGarrett D'Amore 			break;
1517698f87a4SGarrett D'Amore 		}
1518698f87a4SGarrett D'Amore 		break;
1519698f87a4SGarrett D'Amore 	default:
1520698f87a4SGarrett D'Amore 		break;
1521698f87a4SGarrett D'Amore 	}
1522698f87a4SGarrett D'Amore }
1523698f87a4SGarrett D'Amore 
1524698f87a4SGarrett D'Amore static void
post_lb(DECL_ARGS)1525698f87a4SGarrett D'Amore post_lb(DECL_ARGS)
1526698f87a4SGarrett D'Amore {
1527698f87a4SGarrett D'Amore 
1528698f87a4SGarrett D'Amore 	if (SEC_LIBRARY == n->sec)
1529698f87a4SGarrett D'Amore 		outflags |= MMAN_br;
1530698f87a4SGarrett D'Amore }
1531698f87a4SGarrett D'Amore 
1532698f87a4SGarrett D'Amore static int
pre_lk(DECL_ARGS)1533698f87a4SGarrett D'Amore pre_lk(DECL_ARGS)
1534698f87a4SGarrett D'Amore {
1535698f87a4SGarrett D'Amore 	const struct mdoc_node *link, *descr;
1536698f87a4SGarrett D'Amore 
1537698f87a4SGarrett D'Amore 	if (NULL == (link = n->child))
1538698f87a4SGarrett D'Amore 		return(0);
1539698f87a4SGarrett D'Amore 
1540698f87a4SGarrett D'Amore 	if (NULL != (descr = link->next)) {
1541698f87a4SGarrett D'Amore 		font_push('I');
1542698f87a4SGarrett D'Amore 		while (NULL != descr) {
1543698f87a4SGarrett D'Amore 			print_word(descr->string);
1544698f87a4SGarrett D'Amore 			descr = descr->next;
1545698f87a4SGarrett D'Amore 		}
1546698f87a4SGarrett D'Amore 		print_word(":");
1547698f87a4SGarrett D'Amore 		font_pop();
1548698f87a4SGarrett D'Amore 	}
1549698f87a4SGarrett D'Amore 
1550698f87a4SGarrett D'Amore 	font_push('B');
1551698f87a4SGarrett D'Amore 	print_word(link->string);
1552698f87a4SGarrett D'Amore 	font_pop();
1553698f87a4SGarrett D'Amore 	return(0);
1554698f87a4SGarrett D'Amore }
1555698f87a4SGarrett D'Amore 
1556698f87a4SGarrett D'Amore static int
pre_ll(DECL_ARGS)1557*260e9a87SYuri Pankov pre_ll(DECL_ARGS)
1558*260e9a87SYuri Pankov {
1559*260e9a87SYuri Pankov 
1560*260e9a87SYuri Pankov 	print_line(".ll", 0);
1561*260e9a87SYuri Pankov 	return(1);
1562*260e9a87SYuri Pankov }
1563*260e9a87SYuri Pankov 
1564*260e9a87SYuri Pankov static int
pre_li(DECL_ARGS)1565698f87a4SGarrett D'Amore pre_li(DECL_ARGS)
1566698f87a4SGarrett D'Amore {
1567698f87a4SGarrett D'Amore 
1568698f87a4SGarrett D'Amore 	font_push('R');
156995c635efSGarrett D'Amore 	return(1);
157095c635efSGarrett D'Amore }
157195c635efSGarrett D'Amore 
157295c635efSGarrett D'Amore static int
pre_nm(DECL_ARGS)157395c635efSGarrett D'Amore pre_nm(DECL_ARGS)
157495c635efSGarrett D'Amore {
1575698f87a4SGarrett D'Amore 	char	*name;
157695c635efSGarrett D'Amore 
1577698f87a4SGarrett D'Amore 	if (MDOC_BLOCK == n->type) {
1578698f87a4SGarrett D'Amore 		outflags |= MMAN_Bk;
1579698f87a4SGarrett D'Amore 		pre_syn(n);
1580698f87a4SGarrett D'Amore 	}
158195c635efSGarrett D'Amore 	if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
158295c635efSGarrett D'Amore 		return(1);
1583698f87a4SGarrett D'Amore 	name = n->child ? n->child->string : meta->name;
1584698f87a4SGarrett D'Amore 	if (NULL == name)
1585698f87a4SGarrett D'Amore 		return(0);
1586698f87a4SGarrett D'Amore 	if (MDOC_HEAD == n->type) {
1587698f87a4SGarrett D'Amore 		if (NULL == n->parent->prev)
1588698f87a4SGarrett D'Amore 			outflags |= MMAN_sp;
1589698f87a4SGarrett D'Amore 		print_block(".HP", 0);
1590698f87a4SGarrett D'Amore 		printf(" %zun", strlen(name) + 1);
1591698f87a4SGarrett D'Amore 		outflags |= MMAN_nl;
1592698f87a4SGarrett D'Amore 	}
1593698f87a4SGarrett D'Amore 	font_push('B');
159495c635efSGarrett D'Amore 	if (NULL == n->child)
1595698f87a4SGarrett D'Amore 		print_word(meta->name);
159695c635efSGarrett D'Amore 	return(1);
159795c635efSGarrett D'Amore }
159895c635efSGarrett D'Amore 
159995c635efSGarrett D'Amore static void
post_nm(DECL_ARGS)160095c635efSGarrett D'Amore post_nm(DECL_ARGS)
160195c635efSGarrett D'Amore {
160295c635efSGarrett D'Amore 
1603698f87a4SGarrett D'Amore 	switch (n->type) {
1604*260e9a87SYuri Pankov 	case MDOC_BLOCK:
1605698f87a4SGarrett D'Amore 		outflags &= ~MMAN_Bk;
1606698f87a4SGarrett D'Amore 		break;
1607*260e9a87SYuri Pankov 	case MDOC_HEAD:
1608698f87a4SGarrett D'Amore 		/* FALLTHROUGH */
1609*260e9a87SYuri Pankov 	case MDOC_ELEM:
1610*260e9a87SYuri Pankov 		if (n->child != NULL || meta->name != NULL)
1611698f87a4SGarrett D'Amore 			font_pop();
1612698f87a4SGarrett D'Amore 		break;
1613698f87a4SGarrett D'Amore 	default:
1614698f87a4SGarrett D'Amore 		break;
1615698f87a4SGarrett D'Amore 	}
1616698f87a4SGarrett D'Amore }
1617698f87a4SGarrett D'Amore 
1618698f87a4SGarrett D'Amore static int
pre_no(DECL_ARGS)1619698f87a4SGarrett D'Amore pre_no(DECL_ARGS)
1620698f87a4SGarrett D'Amore {
1621698f87a4SGarrett D'Amore 
1622698f87a4SGarrett D'Amore 	outflags |= MMAN_spc_force;
1623698f87a4SGarrett D'Amore 	return(1);
162495c635efSGarrett D'Amore }
162595c635efSGarrett D'Amore 
162695c635efSGarrett D'Amore static int
pre_ns(DECL_ARGS)162795c635efSGarrett D'Amore pre_ns(DECL_ARGS)
162895c635efSGarrett D'Amore {
162995c635efSGarrett D'Amore 
1630698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
163195c635efSGarrett D'Amore 	return(0);
163295c635efSGarrett D'Amore }
163395c635efSGarrett D'Amore 
163495c635efSGarrett D'Amore static void
post_pf(DECL_ARGS)163595c635efSGarrett D'Amore post_pf(DECL_ARGS)
163695c635efSGarrett D'Amore {
163795c635efSGarrett D'Amore 
1638*260e9a87SYuri Pankov 	if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
1639698f87a4SGarrett D'Amore 		outflags &= ~MMAN_spc;
164095c635efSGarrett D'Amore }
164195c635efSGarrett D'Amore 
164295c635efSGarrett D'Amore static int
pre_pp(DECL_ARGS)164395c635efSGarrett D'Amore pre_pp(DECL_ARGS)
164495c635efSGarrett D'Amore {
164595c635efSGarrett D'Amore 
1646698f87a4SGarrett D'Amore 	if (MDOC_It != n->parent->tok)
1647698f87a4SGarrett D'Amore 		outflags |= MMAN_PP;
1648698f87a4SGarrett D'Amore 	outflags |= MMAN_sp | MMAN_nl;
1649698f87a4SGarrett D'Amore 	outflags &= ~MMAN_br;
1650698f87a4SGarrett D'Amore 	return(0);
1651698f87a4SGarrett D'Amore }
1652698f87a4SGarrett D'Amore 
1653698f87a4SGarrett D'Amore static int
pre_rs(DECL_ARGS)1654698f87a4SGarrett D'Amore pre_rs(DECL_ARGS)
1655698f87a4SGarrett D'Amore {
1656698f87a4SGarrett D'Amore 
1657698f87a4SGarrett D'Amore 	if (SEC_SEE_ALSO == n->sec) {
1658698f87a4SGarrett D'Amore 		outflags |= MMAN_PP | MMAN_sp | MMAN_nl;
1659698f87a4SGarrett D'Amore 		outflags &= ~MMAN_br;
1660698f87a4SGarrett D'Amore 	}
166195c635efSGarrett D'Amore 	return(1);
166295c635efSGarrett D'Amore }
166395c635efSGarrett D'Amore 
166495c635efSGarrett D'Amore static int
pre_rv(DECL_ARGS)1665*260e9a87SYuri Pankov pre_rv(DECL_ARGS)
1666*260e9a87SYuri Pankov {
1667*260e9a87SYuri Pankov 	int	 nchild;
1668*260e9a87SYuri Pankov 
1669*260e9a87SYuri Pankov 	outflags |= MMAN_br | MMAN_nl;
1670*260e9a87SYuri Pankov 
1671*260e9a87SYuri Pankov 	nchild = n->nchild;
1672*260e9a87SYuri Pankov 	if (nchild > 0) {
1673*260e9a87SYuri Pankov 		print_word("The");
1674*260e9a87SYuri Pankov 
1675*260e9a87SYuri Pankov 		for (n = n->child; n; n = n->next) {
1676*260e9a87SYuri Pankov 			font_push('B');
1677*260e9a87SYuri Pankov 			print_word(n->string);
1678*260e9a87SYuri Pankov 			font_pop();
1679*260e9a87SYuri Pankov 
1680*260e9a87SYuri Pankov 			outflags &= ~MMAN_spc;
1681*260e9a87SYuri Pankov 			print_word("()");
1682*260e9a87SYuri Pankov 
1683*260e9a87SYuri Pankov 			if (n->next == NULL)
1684*260e9a87SYuri Pankov 				continue;
1685*260e9a87SYuri Pankov 
1686*260e9a87SYuri Pankov 			if (nchild > 2) {
1687*260e9a87SYuri Pankov 				outflags &= ~MMAN_spc;
1688*260e9a87SYuri Pankov 				print_word(",");
1689*260e9a87SYuri Pankov 			}
1690*260e9a87SYuri Pankov 			if (n->next->next == NULL)
1691*260e9a87SYuri Pankov 				print_word("and");
1692*260e9a87SYuri Pankov 		}
1693*260e9a87SYuri Pankov 
1694*260e9a87SYuri Pankov 		if (nchild > 1)
1695*260e9a87SYuri Pankov 			print_word("functions return");
1696*260e9a87SYuri Pankov 		else
1697*260e9a87SYuri Pankov 			print_word("function returns");
1698*260e9a87SYuri Pankov 
1699*260e9a87SYuri Pankov 		print_word("the value\\~0 if successful;");
1700*260e9a87SYuri Pankov 	} else
1701*260e9a87SYuri Pankov 		print_word("Upon successful completion, "
1702*260e9a87SYuri Pankov 		    "the value\\~0 is returned;");
1703*260e9a87SYuri Pankov 
1704*260e9a87SYuri Pankov 	print_word("otherwise the value\\~\\-1 is returned"
1705*260e9a87SYuri Pankov 	    " and the global variable");
1706*260e9a87SYuri Pankov 
1707*260e9a87SYuri Pankov 	font_push('I');
1708*260e9a87SYuri Pankov 	print_word("errno");
1709*260e9a87SYuri Pankov 	font_pop();
1710*260e9a87SYuri Pankov 
1711*260e9a87SYuri Pankov 	print_word("is set to indicate the error.");
1712*260e9a87SYuri Pankov 	outflags |= MMAN_nl;
1713*260e9a87SYuri Pankov 	return(0);
1714*260e9a87SYuri Pankov }
1715*260e9a87SYuri Pankov 
1716*260e9a87SYuri Pankov static int
pre_skip(DECL_ARGS)1717*260e9a87SYuri Pankov pre_skip(DECL_ARGS)
1718*260e9a87SYuri Pankov {
1719*260e9a87SYuri Pankov 
1720*260e9a87SYuri Pankov 	return(0);
1721*260e9a87SYuri Pankov }
1722*260e9a87SYuri Pankov 
1723*260e9a87SYuri Pankov static int
pre_sm(DECL_ARGS)1724698f87a4SGarrett D'Amore pre_sm(DECL_ARGS)
1725698f87a4SGarrett D'Amore {
1726698f87a4SGarrett D'Amore 
1727*260e9a87SYuri Pankov 	if (NULL == n->child)
1728*260e9a87SYuri Pankov 		outflags ^= MMAN_Sm;
1729*260e9a87SYuri Pankov 	else if (0 == strcmp("on", n->child->string))
1730*260e9a87SYuri Pankov 		outflags |= MMAN_Sm;
1731698f87a4SGarrett D'Amore 	else
1732698f87a4SGarrett D'Amore 		outflags &= ~MMAN_Sm;
1733*260e9a87SYuri Pankov 
1734*260e9a87SYuri Pankov 	if (MMAN_Sm & outflags)
1735*260e9a87SYuri Pankov 		outflags |= MMAN_spc;
1736*260e9a87SYuri Pankov 
1737698f87a4SGarrett D'Amore 	return(0);
1738698f87a4SGarrett D'Amore }
1739698f87a4SGarrett D'Amore 
1740698f87a4SGarrett D'Amore static int
pre_sp(DECL_ARGS)174195c635efSGarrett D'Amore pre_sp(DECL_ARGS)
174295c635efSGarrett D'Amore {
174395c635efSGarrett D'Amore 
1744698f87a4SGarrett D'Amore 	if (MMAN_PP & outflags) {
1745698f87a4SGarrett D'Amore 		outflags &= ~MMAN_PP;
1746698f87a4SGarrett D'Amore 		print_line(".PP", 0);
1747698f87a4SGarrett D'Amore 	} else
1748698f87a4SGarrett D'Amore 		print_line(".sp", 0);
174995c635efSGarrett D'Amore 	return(1);
175095c635efSGarrett D'Amore }
175195c635efSGarrett D'Amore 
175295c635efSGarrett D'Amore static void
post_sp(DECL_ARGS)175395c635efSGarrett D'Amore post_sp(DECL_ARGS)
175495c635efSGarrett D'Amore {
175595c635efSGarrett D'Amore 
1756698f87a4SGarrett D'Amore 	outflags |= MMAN_nl;
1757698f87a4SGarrett D'Amore }
1758698f87a4SGarrett D'Amore 
1759698f87a4SGarrett D'Amore static int
pre_sy(DECL_ARGS)1760698f87a4SGarrett D'Amore pre_sy(DECL_ARGS)
1761698f87a4SGarrett D'Amore {
1762698f87a4SGarrett D'Amore 
1763698f87a4SGarrett D'Amore 	font_push('B');
1764698f87a4SGarrett D'Amore 	return(1);
1765698f87a4SGarrett D'Amore }
1766698f87a4SGarrett D'Amore 
1767698f87a4SGarrett D'Amore static int
pre_vt(DECL_ARGS)1768698f87a4SGarrett D'Amore pre_vt(DECL_ARGS)
1769698f87a4SGarrett D'Amore {
1770698f87a4SGarrett D'Amore 
1771698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags) {
1772698f87a4SGarrett D'Amore 		switch (n->type) {
1773*260e9a87SYuri Pankov 		case MDOC_BLOCK:
1774698f87a4SGarrett D'Amore 			pre_syn(n);
1775698f87a4SGarrett D'Amore 			return(1);
1776*260e9a87SYuri Pankov 		case MDOC_BODY:
1777698f87a4SGarrett D'Amore 			break;
1778698f87a4SGarrett D'Amore 		default:
1779698f87a4SGarrett D'Amore 			return(0);
1780698f87a4SGarrett D'Amore 		}
1781698f87a4SGarrett D'Amore 	}
1782698f87a4SGarrett D'Amore 	font_push('I');
1783698f87a4SGarrett D'Amore 	return(1);
1784698f87a4SGarrett D'Amore }
1785698f87a4SGarrett D'Amore 
1786698f87a4SGarrett D'Amore static void
post_vt(DECL_ARGS)1787698f87a4SGarrett D'Amore post_vt(DECL_ARGS)
1788698f87a4SGarrett D'Amore {
1789698f87a4SGarrett D'Amore 
1790698f87a4SGarrett D'Amore 	if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type)
1791698f87a4SGarrett D'Amore 		return;
1792698f87a4SGarrett D'Amore 	font_pop();
179395c635efSGarrett D'Amore }
179495c635efSGarrett D'Amore 
179595c635efSGarrett D'Amore static int
pre_xr(DECL_ARGS)179695c635efSGarrett D'Amore pre_xr(DECL_ARGS)
179795c635efSGarrett D'Amore {
179895c635efSGarrett D'Amore 
179995c635efSGarrett D'Amore 	n = n->child;
180095c635efSGarrett D'Amore 	if (NULL == n)
180195c635efSGarrett D'Amore 		return(0);
1802698f87a4SGarrett D'Amore 	print_node(meta, n);
180395c635efSGarrett D'Amore 	n = n->next;
180495c635efSGarrett D'Amore 	if (NULL == n)
180595c635efSGarrett D'Amore 		return(0);
1806698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1807698f87a4SGarrett D'Amore 	print_word("(");
1808698f87a4SGarrett D'Amore 	print_node(meta, n);
1809698f87a4SGarrett D'Amore 	print_word(")");
181095c635efSGarrett D'Amore 	return(0);
181195c635efSGarrett D'Amore }
181295c635efSGarrett D'Amore 
181395c635efSGarrett D'Amore static int
pre_ux(DECL_ARGS)181495c635efSGarrett D'Amore pre_ux(DECL_ARGS)
181595c635efSGarrett D'Amore {
181695c635efSGarrett D'Amore 
1817698f87a4SGarrett D'Amore 	print_word(manacts[n->tok].prefix);
181895c635efSGarrett D'Amore 	if (NULL == n->child)
181995c635efSGarrett D'Amore 		return(0);
1820698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
1821698f87a4SGarrett D'Amore 	print_word("\\ ");
1822698f87a4SGarrett D'Amore 	outflags &= ~MMAN_spc;
182395c635efSGarrett D'Amore 	return(1);
182495c635efSGarrett D'Amore }
1825