1*698f87a4SGarrett D'Amore /* $Id: mdoc_man.c,v 1.57 2013/12/25 22:00:45 schwarze Exp $ */
295c635efSGarrett D'Amore /*
3*698f87a4SGarrett D'Amore * Copyright (c) 2011, 2012, 2013 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 #ifdef HAVE_CONFIG_H
1895c635efSGarrett D'Amore #include "config.h"
1995c635efSGarrett D'Amore #endif
2095c635efSGarrett D'Amore
21*698f87a4SGarrett 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*698f87a4SGarrett D'Amore #include "out.h"
2795c635efSGarrett D'Amore #include "man.h"
2895c635efSGarrett D'Amore #include "mdoc.h"
2995c635efSGarrett D'Amore #include "main.h"
3095c635efSGarrett D'Amore
31*698f87a4SGarrett D'Amore #define DECL_ARGS const struct mdoc_meta *meta, \
32*698f87a4SGarrett D'Amore const 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);
44*698f87a4SGarrett D'Amore static void font_push(char);
45*698f87a4SGarrett D'Amore static void font_pop(void);
46*698f87a4SGarrett D'Amore static void mid_it(void);
47*698f87a4SGarrett D'Amore static void post__t(DECL_ARGS);
4895c635efSGarrett D'Amore static void post_bd(DECL_ARGS);
49*698f87a4SGarrett D'Amore static void post_bf(DECL_ARGS);
50*698f87a4SGarrett D'Amore static void post_bk(DECL_ARGS);
51*698f87a4SGarrett D'Amore static void post_bl(DECL_ARGS);
5295c635efSGarrett D'Amore static void post_dl(DECL_ARGS);
5395c635efSGarrett D'Amore static void post_enc(DECL_ARGS);
54*698f87a4SGarrett D'Amore static void post_eo(DECL_ARGS);
55*698f87a4SGarrett D'Amore static void post_fa(DECL_ARGS);
56*698f87a4SGarrett D'Amore static void post_fd(DECL_ARGS);
57*698f87a4SGarrett D'Amore static void post_fl(DECL_ARGS);
58*698f87a4SGarrett D'Amore static void post_fn(DECL_ARGS);
59*698f87a4SGarrett D'Amore static void post_fo(DECL_ARGS);
60*698f87a4SGarrett D'Amore static void post_font(DECL_ARGS);
61*698f87a4SGarrett D'Amore static void post_in(DECL_ARGS);
62*698f87a4SGarrett D'Amore static void post_it(DECL_ARGS);
63*698f87a4SGarrett D'Amore static void post_lb(DECL_ARGS);
6495c635efSGarrett D'Amore static void post_nm(DECL_ARGS);
6595c635efSGarrett D'Amore static void post_percent(DECL_ARGS);
6695c635efSGarrett D'Amore static void post_pf(DECL_ARGS);
6795c635efSGarrett D'Amore static void post_sect(DECL_ARGS);
6895c635efSGarrett D'Amore static void post_sp(DECL_ARGS);
69*698f87a4SGarrett D'Amore static void post_vt(DECL_ARGS);
70*698f87a4SGarrett D'Amore static int pre__t(DECL_ARGS);
71*698f87a4SGarrett D'Amore static int pre_an(DECL_ARGS);
7295c635efSGarrett D'Amore static int pre_ap(DECL_ARGS);
7395c635efSGarrett D'Amore static int pre_bd(DECL_ARGS);
74*698f87a4SGarrett D'Amore static int pre_bf(DECL_ARGS);
75*698f87a4SGarrett D'Amore static int pre_bk(DECL_ARGS);
76*698f87a4SGarrett D'Amore static int pre_bl(DECL_ARGS);
7795c635efSGarrett D'Amore static int pre_br(DECL_ARGS);
7895c635efSGarrett D'Amore static int pre_bx(DECL_ARGS);
7995c635efSGarrett D'Amore static int pre_dl(DECL_ARGS);
8095c635efSGarrett D'Amore static int pre_enc(DECL_ARGS);
81*698f87a4SGarrett D'Amore static int pre_em(DECL_ARGS);
82*698f87a4SGarrett D'Amore static int pre_fa(DECL_ARGS);
83*698f87a4SGarrett D'Amore static int pre_fd(DECL_ARGS);
84*698f87a4SGarrett D'Amore static int pre_fl(DECL_ARGS);
85*698f87a4SGarrett D'Amore static int pre_fn(DECL_ARGS);
86*698f87a4SGarrett D'Amore static int pre_fo(DECL_ARGS);
87*698f87a4SGarrett D'Amore static int pre_ft(DECL_ARGS);
88*698f87a4SGarrett D'Amore static int pre_in(DECL_ARGS);
8995c635efSGarrett D'Amore static int pre_it(DECL_ARGS);
90*698f87a4SGarrett D'Amore static int pre_lk(DECL_ARGS);
91*698f87a4SGarrett D'Amore static int pre_li(DECL_ARGS);
9295c635efSGarrett D'Amore static int pre_nm(DECL_ARGS);
93*698f87a4SGarrett D'Amore static int pre_no(DECL_ARGS);
9495c635efSGarrett D'Amore static int pre_ns(DECL_ARGS);
9595c635efSGarrett D'Amore static int pre_pp(DECL_ARGS);
96*698f87a4SGarrett D'Amore static int pre_rs(DECL_ARGS);
97*698f87a4SGarrett D'Amore static int pre_sm(DECL_ARGS);
9895c635efSGarrett D'Amore static int pre_sp(DECL_ARGS);
9995c635efSGarrett D'Amore static int pre_sect(DECL_ARGS);
100*698f87a4SGarrett D'Amore static int pre_sy(DECL_ARGS);
101*698f87a4SGarrett D'Amore static void pre_syn(const struct mdoc_node *);
102*698f87a4SGarrett D'Amore static int pre_vt(DECL_ARGS);
10395c635efSGarrett D'Amore static int pre_ux(DECL_ARGS);
10495c635efSGarrett D'Amore static int pre_xr(DECL_ARGS);
105*698f87a4SGarrett D'Amore static void print_word(const char *);
106*698f87a4SGarrett D'Amore static void print_line(const char *, int);
107*698f87a4SGarrett D'Amore static void print_block(const char *, int);
108*698f87a4SGarrett D'Amore static void print_offs(const char *);
109*698f87a4SGarrett D'Amore static void print_width(const char *,
110*698f87a4SGarrett D'Amore const struct mdoc_node *, size_t);
111*698f87a4SGarrett D'Amore static void print_count(int *);
11295c635efSGarrett D'Amore static void print_node(DECL_ARGS);
11395c635efSGarrett D'Amore
11495c635efSGarrett D'Amore static const struct manact manacts[MDOC_MAX + 1] = {
11595c635efSGarrett D'Amore { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
11695c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Dd */
11795c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Dt */
11895c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Os */
11995c635efSGarrett D'Amore { NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
12095c635efSGarrett D'Amore { NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
12195c635efSGarrett D'Amore { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
12295c635efSGarrett D'Amore { cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
12395c635efSGarrett D'Amore { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
12495c635efSGarrett D'Amore { cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
12595c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ed */
126*698f87a4SGarrett D'Amore { cond_body, pre_bl, post_bl, NULL, NULL }, /* Bl */
12795c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* El */
128*698f87a4SGarrett D'Amore { NULL, pre_it, post_it, NULL, NULL }, /* It */
129*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Ad */
130*698f87a4SGarrett D'Amore { NULL, pre_an, NULL, NULL, NULL }, /* An */
131*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Ar */
132*698f87a4SGarrett D'Amore { NULL, pre_sy, post_font, NULL, NULL }, /* Cd */
133*698f87a4SGarrett D'Amore { NULL, pre_sy, post_font, NULL, NULL }, /* Cm */
134*698f87a4SGarrett D'Amore { NULL, pre_li, post_font, NULL, NULL }, /* Dv */
135*698f87a4SGarrett D'Amore { NULL, pre_li, post_font, NULL, NULL }, /* Er */
136*698f87a4SGarrett D'Amore { NULL, pre_li, post_font, NULL, NULL }, /* Ev */
13795c635efSGarrett D'Amore { NULL, pre_enc, post_enc, "The \\fB",
13895c635efSGarrett D'Amore "\\fP\nutility exits 0 on success, and >0 if an error occurs."
13995c635efSGarrett D'Amore }, /* Ex */
140*698f87a4SGarrett D'Amore { NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
141*698f87a4SGarrett D'Amore { NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
142*698f87a4SGarrett D'Amore { NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
143*698f87a4SGarrett D'Amore { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */
144*698f87a4SGarrett D'Amore { NULL, pre_ft, post_font, NULL, NULL }, /* Ft */
145*698f87a4SGarrett D'Amore { NULL, pre_sy, post_font, NULL, NULL }, /* Ic */
146*698f87a4SGarrett D'Amore { NULL, pre_in, post_in, NULL, NULL }, /* In */
147*698f87a4SGarrett D'Amore { NULL, pre_li, post_font, NULL, NULL }, /* Li */
14895c635efSGarrett D'Amore { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
14995c635efSGarrett D'Amore { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
15095c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
15195c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ot */
152*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Pa */
15395c635efSGarrett D'Amore { NULL, pre_enc, post_enc, "The \\fB",
15495c635efSGarrett D'Amore "\\fP\nfunction returns the value 0 if successful;\n"
15595c635efSGarrett D'Amore "otherwise the value -1 is returned and the global\n"
15695c635efSGarrett D'Amore "variable \\fIerrno\\fP is set to indicate the error."
15795c635efSGarrett D'Amore }, /* Rv */
15895c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* St */
159*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Va */
160*698f87a4SGarrett D'Amore { NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
16195c635efSGarrett D'Amore { NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
162*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %A */
163*698f87a4SGarrett D'Amore { NULL, pre_em, post_percent, NULL, NULL }, /* %B */
164*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %D */
165*698f87a4SGarrett D'Amore { NULL, pre_em, post_percent, NULL, NULL }, /* %I */
166*698f87a4SGarrett D'Amore { NULL, pre_em, post_percent, NULL, NULL }, /* %J */
167*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %N */
168*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %O */
169*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %P */
170*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %R */
171*698f87a4SGarrett D'Amore { NULL, pre__t, post__t, NULL, NULL }, /* %T */
172*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %V */
17395c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ac */
17495c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
17595c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
17695c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* At */
17795c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Bc */
178*698f87a4SGarrett D'Amore { NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
17995c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
18095c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
18195c635efSGarrett D'Amore { NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
18295c635efSGarrett D'Amore { NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
18395c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Db */
18495c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Dc */
185*698f87a4SGarrett D'Amore { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */
186*698f87a4SGarrett D'Amore { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */
187*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ec */
188*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ef */
189*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Em */
190*698f87a4SGarrett D'Amore { NULL, NULL, post_eo, NULL, NULL }, /* Eo */
19195c635efSGarrett D'Amore { NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
192*698f87a4SGarrett D'Amore { NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
193*698f87a4SGarrett D'Amore { NULL, pre_no, NULL, NULL, NULL }, /* No */
19495c635efSGarrett D'Amore { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
19595c635efSGarrett D'Amore { NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
19695c635efSGarrett D'Amore { NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
19795c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Pc */
19895c635efSGarrett D'Amore { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
19995c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
20095c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
20195c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Qc */
202*698f87a4SGarrett D'Amore { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Ql */
20395c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
20495c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
20595c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Re */
206*698f87a4SGarrett D'Amore { cond_body, pre_rs, NULL, NULL, NULL }, /* Rs */
20795c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Sc */
208*698f87a4SGarrett D'Amore { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* So */
209*698f87a4SGarrett D'Amore { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Sq */
210*698f87a4SGarrett D'Amore { NULL, pre_sm, NULL, NULL, NULL }, /* Sm */
211*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Sx */
212*698f87a4SGarrett D'Amore { NULL, pre_sy, post_font, NULL, NULL }, /* Sy */
213*698f87a4SGarrett D'Amore { NULL, pre_li, post_font, NULL, NULL }, /* Tn */
21495c635efSGarrett D'Amore { NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
215*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Xc */
216*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Xo */
217*698f87a4SGarrett D'Amore { NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
218*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Fc */
21995c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
22095c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Oc */
221*698f87a4SGarrett D'Amore { NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
222*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ek */
22395c635efSGarrett D'Amore { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
22495c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Hf */
22595c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Fr */
22695c635efSGarrett D'Amore { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
227*698f87a4SGarrett D'Amore { NULL, NULL, post_lb, NULL, NULL }, /* Lb */
22895c635efSGarrett D'Amore { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
229*698f87a4SGarrett D'Amore { NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
230*698f87a4SGarrett D'Amore { NULL, pre_em, post_font, NULL, NULL }, /* Mt */
23195c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
23295c635efSGarrett D'Amore { cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
23395c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Brc */
234*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %C */
235*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Es */
236*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* En */
23795c635efSGarrett D'Amore { NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
238*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %Q */
23995c635efSGarrett D'Amore { NULL, pre_br, NULL, NULL, NULL }, /* br */
24095c635efSGarrett D'Amore { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
241*698f87a4SGarrett D'Amore { NULL, NULL, post_percent, NULL, NULL }, /* %U */
242*698f87a4SGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* Ta */
24395c635efSGarrett D'Amore { NULL, NULL, NULL, NULL, NULL }, /* ROOT */
24495c635efSGarrett D'Amore };
24595c635efSGarrett D'Amore
246*698f87a4SGarrett D'Amore static int outflags;
247*698f87a4SGarrett D'Amore #define MMAN_spc (1 << 0) /* blank character before next word */
248*698f87a4SGarrett D'Amore #define MMAN_spc_force (1 << 1) /* even before trailing punctuation */
249*698f87a4SGarrett D'Amore #define MMAN_nl (1 << 2) /* break man(7) code line */
250*698f87a4SGarrett D'Amore #define MMAN_br (1 << 3) /* break output line */
251*698f87a4SGarrett D'Amore #define MMAN_sp (1 << 4) /* insert a blank output line */
252*698f87a4SGarrett D'Amore #define MMAN_PP (1 << 5) /* reset indentation etc. */
253*698f87a4SGarrett D'Amore #define MMAN_Sm (1 << 6) /* horizontal spacing mode */
254*698f87a4SGarrett D'Amore #define MMAN_Bk (1 << 7) /* word keep mode */
255*698f87a4SGarrett D'Amore #define MMAN_Bk_susp (1 << 8) /* suspend this (after a macro) */
256*698f87a4SGarrett D'Amore #define MMAN_An_split (1 << 9) /* author mode is "split" */
257*698f87a4SGarrett D'Amore #define MMAN_An_nosplit (1 << 10) /* author mode is "nosplit" */
258*698f87a4SGarrett D'Amore #define MMAN_PD (1 << 11) /* inter-paragraph spacing disabled */
259*698f87a4SGarrett D'Amore #define MMAN_nbrword (1 << 12) /* do not break the next word */
260*698f87a4SGarrett D'Amore
261*698f87a4SGarrett D'Amore #define BL_STACK_MAX 32
262*698f87a4SGarrett D'Amore
263*698f87a4SGarrett D'Amore static size_t Bl_stack[BL_STACK_MAX]; /* offsets [chars] */
264*698f87a4SGarrett D'Amore static int Bl_stack_post[BL_STACK_MAX]; /* add final .RE */
265*698f87a4SGarrett D'Amore static int Bl_stack_len; /* number of nested Bl blocks */
266*698f87a4SGarrett D'Amore static int TPremain; /* characters before tag is full */
267*698f87a4SGarrett D'Amore
268*698f87a4SGarrett D'Amore static struct {
269*698f87a4SGarrett D'Amore char *head;
270*698f87a4SGarrett D'Amore char *tail;
271*698f87a4SGarrett D'Amore size_t size;
272*698f87a4SGarrett D'Amore } fontqueue;
273*698f87a4SGarrett D'Amore
27495c635efSGarrett D'Amore static void
font_push(char newfont)275*698f87a4SGarrett D'Amore font_push(char newfont)
27695c635efSGarrett D'Amore {
27795c635efSGarrett D'Amore
278*698f87a4SGarrett D'Amore if (fontqueue.head + fontqueue.size <= ++fontqueue.tail) {
279*698f87a4SGarrett D'Amore fontqueue.size += 8;
280*698f87a4SGarrett D'Amore fontqueue.head = mandoc_realloc(fontqueue.head,
281*698f87a4SGarrett D'Amore fontqueue.size);
282*698f87a4SGarrett D'Amore }
283*698f87a4SGarrett D'Amore *fontqueue.tail = newfont;
284*698f87a4SGarrett D'Amore print_word("");
285*698f87a4SGarrett D'Amore printf("\\f");
286*698f87a4SGarrett D'Amore putchar(newfont);
287*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
288*698f87a4SGarrett D'Amore }
289*698f87a4SGarrett D'Amore
290*698f87a4SGarrett D'Amore static void
font_pop(void)291*698f87a4SGarrett D'Amore font_pop(void)
292*698f87a4SGarrett D'Amore {
293*698f87a4SGarrett D'Amore
294*698f87a4SGarrett D'Amore if (fontqueue.tail > fontqueue.head)
295*698f87a4SGarrett D'Amore fontqueue.tail--;
296*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
297*698f87a4SGarrett D'Amore print_word("");
298*698f87a4SGarrett D'Amore printf("\\f");
299*698f87a4SGarrett D'Amore putchar(*fontqueue.tail);
300*698f87a4SGarrett D'Amore }
301*698f87a4SGarrett D'Amore
302*698f87a4SGarrett D'Amore static void
print_word(const char * s)303*698f87a4SGarrett D'Amore print_word(const char *s)
304*698f87a4SGarrett D'Amore {
305*698f87a4SGarrett D'Amore
306*698f87a4SGarrett D'Amore if ((MMAN_PP | MMAN_sp | MMAN_br | MMAN_nl) & outflags) {
30795c635efSGarrett D'Amore /*
30895c635efSGarrett D'Amore * If we need a newline, print it now and start afresh.
30995c635efSGarrett D'Amore */
310*698f87a4SGarrett D'Amore if (MMAN_PP & outflags) {
311*698f87a4SGarrett D'Amore if (MMAN_sp & outflags) {
312*698f87a4SGarrett D'Amore if (MMAN_PD & outflags) {
313*698f87a4SGarrett D'Amore printf("\n.PD");
314*698f87a4SGarrett D'Amore outflags &= ~MMAN_PD;
315*698f87a4SGarrett D'Amore }
316*698f87a4SGarrett D'Amore } else if ( ! (MMAN_PD & outflags)) {
317*698f87a4SGarrett D'Amore printf("\n.PD 0");
318*698f87a4SGarrett D'Amore outflags |= MMAN_PD;
319*698f87a4SGarrett D'Amore }
320*698f87a4SGarrett D'Amore printf("\n.PP\n");
321*698f87a4SGarrett D'Amore } else if (MMAN_sp & outflags)
322*698f87a4SGarrett D'Amore printf("\n.sp\n");
323*698f87a4SGarrett D'Amore else if (MMAN_br & outflags)
324*698f87a4SGarrett D'Amore printf("\n.br\n");
325*698f87a4SGarrett D'Amore else if (MMAN_nl & outflags)
32695c635efSGarrett D'Amore putchar('\n');
327*698f87a4SGarrett D'Amore outflags &= ~(MMAN_PP|MMAN_sp|MMAN_br|MMAN_nl|MMAN_spc);
328*698f87a4SGarrett D'Amore if (1 == TPremain)
329*698f87a4SGarrett D'Amore printf(".br\n");
330*698f87a4SGarrett D'Amore TPremain = 0;
331*698f87a4SGarrett D'Amore } else if (MMAN_spc & outflags) {
33295c635efSGarrett D'Amore /*
333*698f87a4SGarrett D'Amore * If we need a space, only print it if
334*698f87a4SGarrett D'Amore * (1) it is forced by `No' or
335*698f87a4SGarrett D'Amore * (2) what follows is not terminating punctuation or
336*698f87a4SGarrett D'Amore * (3) what follows is longer than one character.
33795c635efSGarrett D'Amore */
338*698f87a4SGarrett D'Amore if (MMAN_spc_force & outflags || '\0' == s[0] ||
339*698f87a4SGarrett D'Amore NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
340*698f87a4SGarrett D'Amore if (MMAN_Bk & outflags &&
341*698f87a4SGarrett D'Amore ! (MMAN_Bk_susp & outflags))
342*698f87a4SGarrett D'Amore putchar('\\');
34395c635efSGarrett D'Amore putchar(' ');
344*698f87a4SGarrett D'Amore if (TPremain)
345*698f87a4SGarrett D'Amore TPremain--;
346*698f87a4SGarrett D'Amore }
347*698f87a4SGarrett D'Amore }
34895c635efSGarrett D'Amore
34995c635efSGarrett D'Amore /*
35095c635efSGarrett D'Amore * Reassign needing space if we're not following opening
35195c635efSGarrett D'Amore * punctuation.
35295c635efSGarrett D'Amore */
353*698f87a4SGarrett D'Amore if (MMAN_Sm & outflags && ('\0' == s[0] ||
354*698f87a4SGarrett D'Amore (('(' != s[0] && '[' != s[0]) || '\0' != s[1])))
355*698f87a4SGarrett D'Amore outflags |= MMAN_spc;
356*698f87a4SGarrett D'Amore else
357*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
358*698f87a4SGarrett D'Amore outflags &= ~(MMAN_spc_force | MMAN_Bk_susp);
35995c635efSGarrett D'Amore
36095c635efSGarrett D'Amore for ( ; *s; s++) {
36195c635efSGarrett D'Amore switch (*s) {
36295c635efSGarrett D'Amore case (ASCII_NBRSP):
363*698f87a4SGarrett D'Amore printf("\\ ");
36495c635efSGarrett D'Amore break;
36595c635efSGarrett D'Amore case (ASCII_HYPH):
36695c635efSGarrett D'Amore putchar('-');
36795c635efSGarrett D'Amore break;
368*698f87a4SGarrett D'Amore case (' '):
369*698f87a4SGarrett D'Amore if (MMAN_nbrword & outflags) {
370*698f87a4SGarrett D'Amore printf("\\ ");
371*698f87a4SGarrett D'Amore break;
372*698f87a4SGarrett D'Amore }
373*698f87a4SGarrett D'Amore /* FALLTHROUGH */
37495c635efSGarrett D'Amore default:
37595c635efSGarrett D'Amore putchar((unsigned char)*s);
37695c635efSGarrett D'Amore break;
37795c635efSGarrett D'Amore }
378*698f87a4SGarrett D'Amore if (TPremain)
379*698f87a4SGarrett D'Amore TPremain--;
38095c635efSGarrett D'Amore }
381*698f87a4SGarrett D'Amore outflags &= ~MMAN_nbrword;
382*698f87a4SGarrett D'Amore }
383*698f87a4SGarrett D'Amore
384*698f87a4SGarrett D'Amore static void
print_line(const char * s,int newflags)385*698f87a4SGarrett D'Amore print_line(const char *s, int newflags)
386*698f87a4SGarrett D'Amore {
387*698f87a4SGarrett D'Amore
388*698f87a4SGarrett D'Amore outflags &= ~MMAN_br;
389*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
390*698f87a4SGarrett D'Amore print_word(s);
391*698f87a4SGarrett D'Amore outflags |= newflags;
392*698f87a4SGarrett D'Amore }
393*698f87a4SGarrett D'Amore
394*698f87a4SGarrett D'Amore static void
print_block(const char * s,int newflags)395*698f87a4SGarrett D'Amore print_block(const char *s, int newflags)
396*698f87a4SGarrett D'Amore {
397*698f87a4SGarrett D'Amore
398*698f87a4SGarrett D'Amore outflags &= ~MMAN_PP;
399*698f87a4SGarrett D'Amore if (MMAN_sp & outflags) {
400*698f87a4SGarrett D'Amore outflags &= ~(MMAN_sp | MMAN_br);
401*698f87a4SGarrett D'Amore if (MMAN_PD & outflags) {
402*698f87a4SGarrett D'Amore print_line(".PD", 0);
403*698f87a4SGarrett D'Amore outflags &= ~MMAN_PD;
404*698f87a4SGarrett D'Amore }
405*698f87a4SGarrett D'Amore } else if (! (MMAN_PD & outflags))
406*698f87a4SGarrett D'Amore print_line(".PD 0", MMAN_PD);
407*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
408*698f87a4SGarrett D'Amore print_word(s);
409*698f87a4SGarrett D'Amore outflags |= MMAN_Bk_susp | newflags;
410*698f87a4SGarrett D'Amore }
411*698f87a4SGarrett D'Amore
412*698f87a4SGarrett D'Amore static void
print_offs(const char * v)413*698f87a4SGarrett D'Amore print_offs(const char *v)
414*698f87a4SGarrett D'Amore {
415*698f87a4SGarrett D'Amore char buf[24];
416*698f87a4SGarrett D'Amore struct roffsu su;
417*698f87a4SGarrett D'Amore size_t sz;
418*698f87a4SGarrett D'Amore
419*698f87a4SGarrett D'Amore print_line(".RS", MMAN_Bk_susp);
420*698f87a4SGarrett D'Amore
421*698f87a4SGarrett D'Amore /* Convert v into a number (of characters). */
422*698f87a4SGarrett D'Amore if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
423*698f87a4SGarrett D'Amore sz = 0;
424*698f87a4SGarrett D'Amore else if (0 == strcmp(v, "indent"))
425*698f87a4SGarrett D'Amore sz = 6;
426*698f87a4SGarrett D'Amore else if (0 == strcmp(v, "indent-two"))
427*698f87a4SGarrett D'Amore sz = 12;
428*698f87a4SGarrett D'Amore else if (a2roffsu(v, &su, SCALE_MAX)) {
429*698f87a4SGarrett D'Amore if (SCALE_EN == su.unit)
430*698f87a4SGarrett D'Amore sz = su.scale;
431*698f87a4SGarrett D'Amore else {
432*698f87a4SGarrett D'Amore /*
433*698f87a4SGarrett D'Amore * XXX
434*698f87a4SGarrett D'Amore * If we are inside an enclosing list,
435*698f87a4SGarrett D'Amore * there is no easy way to add the two
436*698f87a4SGarrett D'Amore * indentations because they are provided
437*698f87a4SGarrett D'Amore * in terms of different units.
438*698f87a4SGarrett D'Amore */
439*698f87a4SGarrett D'Amore print_word(v);
440*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
441*698f87a4SGarrett D'Amore return;
442*698f87a4SGarrett D'Amore }
443*698f87a4SGarrett D'Amore } else
444*698f87a4SGarrett D'Amore sz = strlen(v);
445*698f87a4SGarrett D'Amore
446*698f87a4SGarrett D'Amore /*
447*698f87a4SGarrett D'Amore * We are inside an enclosing list.
448*698f87a4SGarrett D'Amore * Add the two indentations.
449*698f87a4SGarrett D'Amore */
450*698f87a4SGarrett D'Amore if (Bl_stack_len)
451*698f87a4SGarrett D'Amore sz += Bl_stack[Bl_stack_len - 1];
452*698f87a4SGarrett D'Amore
453*698f87a4SGarrett D'Amore snprintf(buf, sizeof(buf), "%zun", sz);
454*698f87a4SGarrett D'Amore print_word(buf);
455*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
456*698f87a4SGarrett D'Amore }
457*698f87a4SGarrett D'Amore
458*698f87a4SGarrett D'Amore /*
459*698f87a4SGarrett D'Amore * Set up the indentation for a list item; used from pre_it().
460*698f87a4SGarrett D'Amore */
461*698f87a4SGarrett D'Amore void
print_width(const char * v,const struct mdoc_node * child,size_t defsz)462*698f87a4SGarrett D'Amore print_width(const char *v, const struct mdoc_node *child, size_t defsz)
463*698f87a4SGarrett D'Amore {
464*698f87a4SGarrett D'Amore char buf[24];
465*698f87a4SGarrett D'Amore struct roffsu su;
466*698f87a4SGarrett D'Amore size_t sz, chsz;
467*698f87a4SGarrett D'Amore int numeric, remain;
468*698f87a4SGarrett D'Amore
469*698f87a4SGarrett D'Amore numeric = 1;
470*698f87a4SGarrett D'Amore remain = 0;
471*698f87a4SGarrett D'Amore
472*698f87a4SGarrett D'Amore /* Convert v into a number (of characters). */
473*698f87a4SGarrett D'Amore if (NULL == v)
474*698f87a4SGarrett D'Amore sz = defsz;
475*698f87a4SGarrett D'Amore else if (a2roffsu(v, &su, SCALE_MAX)) {
476*698f87a4SGarrett D'Amore if (SCALE_EN == su.unit)
477*698f87a4SGarrett D'Amore sz = su.scale;
478*698f87a4SGarrett D'Amore else {
479*698f87a4SGarrett D'Amore sz = 0;
480*698f87a4SGarrett D'Amore numeric = 0;
481*698f87a4SGarrett D'Amore }
482*698f87a4SGarrett D'Amore } else
483*698f87a4SGarrett D'Amore sz = strlen(v);
484*698f87a4SGarrett D'Amore
485*698f87a4SGarrett D'Amore /* XXX Rough estimation, might have multiple parts. */
486*698f87a4SGarrett D'Amore chsz = (NULL != child && MDOC_TEXT == child->type) ?
487*698f87a4SGarrett D'Amore strlen(child->string) : 0;
488*698f87a4SGarrett D'Amore
489*698f87a4SGarrett D'Amore /* Maybe we are inside an enclosing list? */
490*698f87a4SGarrett D'Amore mid_it();
491*698f87a4SGarrett D'Amore
492*698f87a4SGarrett D'Amore /*
493*698f87a4SGarrett D'Amore * Save our own indentation,
494*698f87a4SGarrett D'Amore * such that child lists can use it.
495*698f87a4SGarrett D'Amore */
496*698f87a4SGarrett D'Amore Bl_stack[Bl_stack_len++] = sz + 2;
497*698f87a4SGarrett D'Amore
498*698f87a4SGarrett D'Amore /* Set up the current list. */
499*698f87a4SGarrett D'Amore if (defsz && chsz > sz)
500*698f87a4SGarrett D'Amore print_block(".HP", 0);
501*698f87a4SGarrett D'Amore else {
502*698f87a4SGarrett D'Amore print_block(".TP", 0);
503*698f87a4SGarrett D'Amore remain = sz + 2;
504*698f87a4SGarrett D'Amore }
505*698f87a4SGarrett D'Amore if (numeric) {
506*698f87a4SGarrett D'Amore snprintf(buf, sizeof(buf), "%zun", sz + 2);
507*698f87a4SGarrett D'Amore print_word(buf);
508*698f87a4SGarrett D'Amore } else
509*698f87a4SGarrett D'Amore print_word(v);
510*698f87a4SGarrett D'Amore TPremain = remain;
511*698f87a4SGarrett D'Amore }
512*698f87a4SGarrett D'Amore
513*698f87a4SGarrett D'Amore void
print_count(int * count)514*698f87a4SGarrett D'Amore print_count(int *count)
515*698f87a4SGarrett D'Amore {
516*698f87a4SGarrett D'Amore char buf[12];
517*698f87a4SGarrett D'Amore
518*698f87a4SGarrett D'Amore snprintf(buf, sizeof(buf), "%d.", ++*count);
519*698f87a4SGarrett D'Amore print_word(buf);
52095c635efSGarrett D'Amore }
52195c635efSGarrett D'Amore
52295c635efSGarrett D'Amore void
man_man(void * arg,const struct man * man)52395c635efSGarrett D'Amore man_man(void *arg, const struct man *man)
52495c635efSGarrett D'Amore {
52595c635efSGarrett D'Amore
52695c635efSGarrett D'Amore /*
52795c635efSGarrett D'Amore * Dump the keep buffer.
52895c635efSGarrett D'Amore * We're guaranteed by now that this exists (is non-NULL).
52995c635efSGarrett D'Amore * Flush stdout afterward, just in case.
53095c635efSGarrett D'Amore */
53195c635efSGarrett D'Amore fputs(mparse_getkeep(man_mparse(man)), stdout);
53295c635efSGarrett D'Amore fflush(stdout);
53395c635efSGarrett D'Amore }
53495c635efSGarrett D'Amore
53595c635efSGarrett D'Amore void
man_mdoc(void * arg,const struct mdoc * mdoc)53695c635efSGarrett D'Amore man_mdoc(void *arg, const struct mdoc *mdoc)
53795c635efSGarrett D'Amore {
538*698f87a4SGarrett D'Amore const struct mdoc_meta *meta;
53995c635efSGarrett D'Amore const struct mdoc_node *n;
54095c635efSGarrett D'Amore
541*698f87a4SGarrett D'Amore meta = mdoc_meta(mdoc);
54295c635efSGarrett D'Amore n = mdoc_node(mdoc);
54395c635efSGarrett D'Amore
544*698f87a4SGarrett D'Amore printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
545*698f87a4SGarrett D'Amore meta->title, meta->msec, meta->date,
546*698f87a4SGarrett D'Amore meta->os, meta->vol);
54795c635efSGarrett D'Amore
548*698f87a4SGarrett D'Amore /* Disable hyphenation and if nroff, disable justification. */
549*698f87a4SGarrett D'Amore printf(".nh\n.if n .ad l");
55095c635efSGarrett D'Amore
551*698f87a4SGarrett D'Amore outflags = MMAN_nl | MMAN_Sm;
552*698f87a4SGarrett D'Amore if (0 == fontqueue.size) {
553*698f87a4SGarrett D'Amore fontqueue.size = 8;
554*698f87a4SGarrett D'Amore fontqueue.head = fontqueue.tail = mandoc_malloc(8);
555*698f87a4SGarrett D'Amore *fontqueue.tail = 'R';
556*698f87a4SGarrett D'Amore }
557*698f87a4SGarrett D'Amore print_node(meta, n);
55895c635efSGarrett D'Amore putchar('\n');
55995c635efSGarrett D'Amore }
56095c635efSGarrett D'Amore
56195c635efSGarrett D'Amore static void
print_node(DECL_ARGS)56295c635efSGarrett D'Amore print_node(DECL_ARGS)
56395c635efSGarrett D'Amore {
564*698f87a4SGarrett D'Amore const struct mdoc_node *sub;
56595c635efSGarrett D'Amore const struct manact *act;
56695c635efSGarrett D'Amore int cond, do_sub;
56795c635efSGarrett D'Amore
56895c635efSGarrett D'Amore /*
56995c635efSGarrett D'Amore * Break the line if we were parsed subsequent the current node.
57095c635efSGarrett D'Amore * This makes the page structure be more consistent.
57195c635efSGarrett D'Amore */
572*698f87a4SGarrett D'Amore if (MMAN_spc & outflags && MDOC_LINE & n->flags)
573*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
57495c635efSGarrett D'Amore
57595c635efSGarrett D'Amore act = NULL;
57695c635efSGarrett D'Amore cond = 0;
57795c635efSGarrett D'Amore do_sub = 1;
57895c635efSGarrett D'Amore
57995c635efSGarrett D'Amore if (MDOC_TEXT == n->type) {
58095c635efSGarrett D'Amore /*
58195c635efSGarrett D'Amore * Make sure that we don't happen to start with a
58295c635efSGarrett D'Amore * control character at the start of a line.
58395c635efSGarrett D'Amore */
584*698f87a4SGarrett D'Amore if (MMAN_nl & outflags && ('.' == *n->string ||
58595c635efSGarrett D'Amore '\'' == *n->string)) {
586*698f87a4SGarrett D'Amore print_word("");
587*698f87a4SGarrett D'Amore printf("\\&");
588*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
58995c635efSGarrett D'Amore }
590*698f87a4SGarrett D'Amore print_word(n->string);
59195c635efSGarrett D'Amore } else {
59295c635efSGarrett D'Amore /*
59395c635efSGarrett D'Amore * Conditionally run the pre-node action handler for a
59495c635efSGarrett D'Amore * node.
59595c635efSGarrett D'Amore */
59695c635efSGarrett D'Amore act = manacts + n->tok;
597*698f87a4SGarrett D'Amore cond = NULL == act->cond || (*act->cond)(meta, n);
59895c635efSGarrett D'Amore if (cond && act->pre)
599*698f87a4SGarrett D'Amore do_sub = (*act->pre)(meta, n);
60095c635efSGarrett D'Amore }
60195c635efSGarrett D'Amore
60295c635efSGarrett D'Amore /*
60395c635efSGarrett D'Amore * Conditionally run all child nodes.
60495c635efSGarrett D'Amore * Note that this iterates over children instead of using
60595c635efSGarrett D'Amore * recursion. This prevents unnecessary depth in the stack.
60695c635efSGarrett D'Amore */
60795c635efSGarrett D'Amore if (do_sub)
60895c635efSGarrett D'Amore for (sub = n->child; sub; sub = sub->next)
609*698f87a4SGarrett D'Amore print_node(meta, sub);
61095c635efSGarrett D'Amore
61195c635efSGarrett D'Amore /*
61295c635efSGarrett D'Amore * Lastly, conditionally run the post-node handler.
61395c635efSGarrett D'Amore */
61495c635efSGarrett D'Amore if (cond && act->post)
615*698f87a4SGarrett D'Amore (*act->post)(meta, n);
61695c635efSGarrett D'Amore }
61795c635efSGarrett D'Amore
61895c635efSGarrett D'Amore static int
cond_head(DECL_ARGS)61995c635efSGarrett D'Amore cond_head(DECL_ARGS)
62095c635efSGarrett D'Amore {
62195c635efSGarrett D'Amore
62295c635efSGarrett D'Amore return(MDOC_HEAD == n->type);
62395c635efSGarrett D'Amore }
62495c635efSGarrett D'Amore
62595c635efSGarrett D'Amore static int
cond_body(DECL_ARGS)62695c635efSGarrett D'Amore cond_body(DECL_ARGS)
62795c635efSGarrett D'Amore {
62895c635efSGarrett D'Amore
62995c635efSGarrett D'Amore return(MDOC_BODY == n->type);
63095c635efSGarrett D'Amore }
63195c635efSGarrett D'Amore
63295c635efSGarrett D'Amore static int
pre_enc(DECL_ARGS)63395c635efSGarrett D'Amore pre_enc(DECL_ARGS)
63495c635efSGarrett D'Amore {
63595c635efSGarrett D'Amore const char *prefix;
63695c635efSGarrett D'Amore
63795c635efSGarrett D'Amore prefix = manacts[n->tok].prefix;
63895c635efSGarrett D'Amore if (NULL == prefix)
63995c635efSGarrett D'Amore return(1);
640*698f87a4SGarrett D'Amore print_word(prefix);
641*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
64295c635efSGarrett D'Amore return(1);
64395c635efSGarrett D'Amore }
64495c635efSGarrett D'Amore
64595c635efSGarrett D'Amore static void
post_enc(DECL_ARGS)64695c635efSGarrett D'Amore post_enc(DECL_ARGS)
64795c635efSGarrett D'Amore {
64895c635efSGarrett D'Amore const char *suffix;
64995c635efSGarrett D'Amore
65095c635efSGarrett D'Amore suffix = manacts[n->tok].suffix;
65195c635efSGarrett D'Amore if (NULL == suffix)
65295c635efSGarrett D'Amore return;
653*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
654*698f87a4SGarrett D'Amore print_word(suffix);
65595c635efSGarrett D'Amore }
65695c635efSGarrett D'Amore
657*698f87a4SGarrett D'Amore static void
post_font(DECL_ARGS)658*698f87a4SGarrett D'Amore post_font(DECL_ARGS)
659*698f87a4SGarrett D'Amore {
660*698f87a4SGarrett D'Amore
661*698f87a4SGarrett D'Amore font_pop();
662*698f87a4SGarrett D'Amore }
663*698f87a4SGarrett D'Amore
66495c635efSGarrett D'Amore static void
post_percent(DECL_ARGS)66595c635efSGarrett D'Amore post_percent(DECL_ARGS)
66695c635efSGarrett D'Amore {
66795c635efSGarrett D'Amore
668*698f87a4SGarrett D'Amore if (pre_em == manacts[n->tok].pre)
669*698f87a4SGarrett D'Amore font_pop();
670*698f87a4SGarrett D'Amore if (n->next) {
671*698f87a4SGarrett D'Amore print_word(",");
672*698f87a4SGarrett D'Amore if (n->prev && n->prev->tok == n->tok &&
673*698f87a4SGarrett D'Amore n->next->tok == n->tok)
674*698f87a4SGarrett D'Amore print_word("and");
675*698f87a4SGarrett D'Amore } else {
676*698f87a4SGarrett D'Amore print_word(".");
677*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
67895c635efSGarrett D'Amore }
67995c635efSGarrett D'Amore }
68095c635efSGarrett D'Amore
681*698f87a4SGarrett D'Amore static int
pre__t(DECL_ARGS)682*698f87a4SGarrett D'Amore pre__t(DECL_ARGS)
683*698f87a4SGarrett D'Amore {
684*698f87a4SGarrett D'Amore
685*698f87a4SGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok &&
686*698f87a4SGarrett D'Amore n->parent->norm->Rs.quote_T) {
687*698f87a4SGarrett D'Amore print_word("");
688*698f87a4SGarrett D'Amore putchar('\"');
689*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
690*698f87a4SGarrett D'Amore } else
691*698f87a4SGarrett D'Amore font_push('I');
692*698f87a4SGarrett D'Amore return(1);
693*698f87a4SGarrett D'Amore }
694*698f87a4SGarrett D'Amore
695*698f87a4SGarrett D'Amore static void
post__t(DECL_ARGS)696*698f87a4SGarrett D'Amore post__t(DECL_ARGS)
697*698f87a4SGarrett D'Amore {
698*698f87a4SGarrett D'Amore
699*698f87a4SGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok &&
700*698f87a4SGarrett D'Amore n->parent->norm->Rs.quote_T) {
701*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
702*698f87a4SGarrett D'Amore print_word("");
703*698f87a4SGarrett D'Amore putchar('\"');
704*698f87a4SGarrett D'Amore } else
705*698f87a4SGarrett D'Amore font_pop();
706*698f87a4SGarrett D'Amore post_percent(meta, n);
707*698f87a4SGarrett D'Amore }
708*698f87a4SGarrett D'Amore
70995c635efSGarrett D'Amore /*
71095c635efSGarrett D'Amore * Print before a section header.
71195c635efSGarrett D'Amore */
71295c635efSGarrett D'Amore static int
pre_sect(DECL_ARGS)71395c635efSGarrett D'Amore pre_sect(DECL_ARGS)
71495c635efSGarrett D'Amore {
71595c635efSGarrett D'Amore
716*698f87a4SGarrett D'Amore if (MDOC_HEAD == n->type) {
717*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
718*698f87a4SGarrett D'Amore print_block(manacts[n->tok].prefix, 0);
719*698f87a4SGarrett D'Amore print_word("");
720*698f87a4SGarrett D'Amore putchar('\"');
721*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
722*698f87a4SGarrett D'Amore }
72395c635efSGarrett D'Amore return(1);
72495c635efSGarrett D'Amore }
72595c635efSGarrett D'Amore
72695c635efSGarrett D'Amore /*
72795c635efSGarrett D'Amore * Print subsequent a section header.
72895c635efSGarrett D'Amore */
72995c635efSGarrett D'Amore static void
post_sect(DECL_ARGS)73095c635efSGarrett D'Amore post_sect(DECL_ARGS)
73195c635efSGarrett D'Amore {
73295c635efSGarrett D'Amore
73395c635efSGarrett D'Amore if (MDOC_HEAD != n->type)
73495c635efSGarrett D'Amore return;
735*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
736*698f87a4SGarrett D'Amore print_word("");
737*698f87a4SGarrett D'Amore putchar('\"');
738*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
739*698f87a4SGarrett D'Amore if (MDOC_Sh == n->tok && SEC_AUTHORS == n->sec)
740*698f87a4SGarrett D'Amore outflags &= ~(MMAN_An_split | MMAN_An_nosplit);
741*698f87a4SGarrett D'Amore }
742*698f87a4SGarrett D'Amore
743*698f87a4SGarrett D'Amore /* See mdoc_term.c, synopsis_pre() for comments. */
744*698f87a4SGarrett D'Amore static void
pre_syn(const struct mdoc_node * n)745*698f87a4SGarrett D'Amore pre_syn(const struct mdoc_node *n)
746*698f87a4SGarrett D'Amore {
747*698f87a4SGarrett D'Amore
748*698f87a4SGarrett D'Amore if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
749*698f87a4SGarrett D'Amore return;
750*698f87a4SGarrett D'Amore
751*698f87a4SGarrett D'Amore if (n->prev->tok == n->tok &&
752*698f87a4SGarrett D'Amore MDOC_Ft != n->tok &&
753*698f87a4SGarrett D'Amore MDOC_Fo != n->tok &&
754*698f87a4SGarrett D'Amore MDOC_Fn != n->tok) {
755*698f87a4SGarrett D'Amore outflags |= MMAN_br;
756*698f87a4SGarrett D'Amore return;
757*698f87a4SGarrett D'Amore }
758*698f87a4SGarrett D'Amore
759*698f87a4SGarrett D'Amore switch (n->prev->tok) {
760*698f87a4SGarrett D'Amore case (MDOC_Fd):
761*698f87a4SGarrett D'Amore /* FALLTHROUGH */
762*698f87a4SGarrett D'Amore case (MDOC_Fn):
763*698f87a4SGarrett D'Amore /* FALLTHROUGH */
764*698f87a4SGarrett D'Amore case (MDOC_Fo):
765*698f87a4SGarrett D'Amore /* FALLTHROUGH */
766*698f87a4SGarrett D'Amore case (MDOC_In):
767*698f87a4SGarrett D'Amore /* FALLTHROUGH */
768*698f87a4SGarrett D'Amore case (MDOC_Vt):
769*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
770*698f87a4SGarrett D'Amore break;
771*698f87a4SGarrett D'Amore case (MDOC_Ft):
772*698f87a4SGarrett D'Amore if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
773*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
774*698f87a4SGarrett D'Amore break;
775*698f87a4SGarrett D'Amore }
776*698f87a4SGarrett D'Amore /* FALLTHROUGH */
777*698f87a4SGarrett D'Amore default:
778*698f87a4SGarrett D'Amore outflags |= MMAN_br;
779*698f87a4SGarrett D'Amore break;
780*698f87a4SGarrett D'Amore }
781*698f87a4SGarrett D'Amore }
782*698f87a4SGarrett D'Amore
783*698f87a4SGarrett D'Amore static int
pre_an(DECL_ARGS)784*698f87a4SGarrett D'Amore pre_an(DECL_ARGS)
785*698f87a4SGarrett D'Amore {
786*698f87a4SGarrett D'Amore
787*698f87a4SGarrett D'Amore switch (n->norm->An.auth) {
788*698f87a4SGarrett D'Amore case (AUTH_split):
789*698f87a4SGarrett D'Amore outflags &= ~MMAN_An_nosplit;
790*698f87a4SGarrett D'Amore outflags |= MMAN_An_split;
791*698f87a4SGarrett D'Amore return(0);
792*698f87a4SGarrett D'Amore case (AUTH_nosplit):
793*698f87a4SGarrett D'Amore outflags &= ~MMAN_An_split;
794*698f87a4SGarrett D'Amore outflags |= MMAN_An_nosplit;
795*698f87a4SGarrett D'Amore return(0);
796*698f87a4SGarrett D'Amore default:
797*698f87a4SGarrett D'Amore if (MMAN_An_split & outflags)
798*698f87a4SGarrett D'Amore outflags |= MMAN_br;
799*698f87a4SGarrett D'Amore else if (SEC_AUTHORS == n->sec &&
800*698f87a4SGarrett D'Amore ! (MMAN_An_nosplit & outflags))
801*698f87a4SGarrett D'Amore outflags |= MMAN_An_split;
802*698f87a4SGarrett D'Amore return(1);
803*698f87a4SGarrett D'Amore }
80495c635efSGarrett D'Amore }
80595c635efSGarrett D'Amore
80695c635efSGarrett D'Amore static int
pre_ap(DECL_ARGS)80795c635efSGarrett D'Amore pre_ap(DECL_ARGS)
80895c635efSGarrett D'Amore {
80995c635efSGarrett D'Amore
810*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
811*698f87a4SGarrett D'Amore print_word("'");
812*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
81395c635efSGarrett D'Amore return(0);
81495c635efSGarrett D'Amore }
81595c635efSGarrett D'Amore
81695c635efSGarrett D'Amore static int
pre_bd(DECL_ARGS)81795c635efSGarrett D'Amore pre_bd(DECL_ARGS)
81895c635efSGarrett D'Amore {
81995c635efSGarrett D'Amore
820*698f87a4SGarrett D'Amore outflags &= ~(MMAN_PP | MMAN_sp | MMAN_br);
821*698f87a4SGarrett D'Amore
82295c635efSGarrett D'Amore if (DISP_unfilled == n->norm->Bd.type ||
823*698f87a4SGarrett D'Amore DISP_literal == n->norm->Bd.type)
824*698f87a4SGarrett D'Amore print_line(".nf", 0);
825*698f87a4SGarrett D'Amore if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
826*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
827*698f87a4SGarrett D'Amore print_offs(n->norm->Bd.offs);
82895c635efSGarrett D'Amore return(1);
82995c635efSGarrett D'Amore }
83095c635efSGarrett D'Amore
83195c635efSGarrett D'Amore static void
post_bd(DECL_ARGS)83295c635efSGarrett D'Amore post_bd(DECL_ARGS)
83395c635efSGarrett D'Amore {
83495c635efSGarrett D'Amore
835*698f87a4SGarrett D'Amore /* Close out this display. */
836*698f87a4SGarrett D'Amore print_line(".RE", MMAN_nl);
83795c635efSGarrett D'Amore if (DISP_unfilled == n->norm->Bd.type ||
838*698f87a4SGarrett D'Amore DISP_literal == n->norm->Bd.type)
839*698f87a4SGarrett D'Amore print_line(".fi", MMAN_nl);
840*698f87a4SGarrett D'Amore
841*698f87a4SGarrett D'Amore /* Maybe we are inside an enclosing list? */
842*698f87a4SGarrett D'Amore if (NULL != n->parent->next)
843*698f87a4SGarrett D'Amore mid_it();
84495c635efSGarrett D'Amore }
845*698f87a4SGarrett D'Amore
846*698f87a4SGarrett D'Amore static int
pre_bf(DECL_ARGS)847*698f87a4SGarrett D'Amore pre_bf(DECL_ARGS)
848*698f87a4SGarrett D'Amore {
849*698f87a4SGarrett D'Amore
850*698f87a4SGarrett D'Amore switch (n->type) {
851*698f87a4SGarrett D'Amore case (MDOC_BLOCK):
852*698f87a4SGarrett D'Amore return(1);
853*698f87a4SGarrett D'Amore case (MDOC_BODY):
854*698f87a4SGarrett D'Amore break;
855*698f87a4SGarrett D'Amore default:
856*698f87a4SGarrett D'Amore return(0);
857*698f87a4SGarrett D'Amore }
858*698f87a4SGarrett D'Amore switch (n->norm->Bf.font) {
859*698f87a4SGarrett D'Amore case (FONT_Em):
860*698f87a4SGarrett D'Amore font_push('I');
861*698f87a4SGarrett D'Amore break;
862*698f87a4SGarrett D'Amore case (FONT_Sy):
863*698f87a4SGarrett D'Amore font_push('B');
864*698f87a4SGarrett D'Amore break;
865*698f87a4SGarrett D'Amore default:
866*698f87a4SGarrett D'Amore font_push('R');
867*698f87a4SGarrett D'Amore break;
868*698f87a4SGarrett D'Amore }
869*698f87a4SGarrett D'Amore return(1);
870*698f87a4SGarrett D'Amore }
871*698f87a4SGarrett D'Amore
872*698f87a4SGarrett D'Amore static void
post_bf(DECL_ARGS)873*698f87a4SGarrett D'Amore post_bf(DECL_ARGS)
874*698f87a4SGarrett D'Amore {
875*698f87a4SGarrett D'Amore
876*698f87a4SGarrett D'Amore if (MDOC_BODY == n->type)
877*698f87a4SGarrett D'Amore font_pop();
878*698f87a4SGarrett D'Amore }
879*698f87a4SGarrett D'Amore
880*698f87a4SGarrett D'Amore static int
pre_bk(DECL_ARGS)881*698f87a4SGarrett D'Amore pre_bk(DECL_ARGS)
882*698f87a4SGarrett D'Amore {
883*698f87a4SGarrett D'Amore
884*698f87a4SGarrett D'Amore switch (n->type) {
885*698f87a4SGarrett D'Amore case (MDOC_BLOCK):
886*698f87a4SGarrett D'Amore return(1);
887*698f87a4SGarrett D'Amore case (MDOC_BODY):
888*698f87a4SGarrett D'Amore outflags |= MMAN_Bk;
889*698f87a4SGarrett D'Amore return(1);
890*698f87a4SGarrett D'Amore default:
891*698f87a4SGarrett D'Amore return(0);
892*698f87a4SGarrett D'Amore }
893*698f87a4SGarrett D'Amore }
894*698f87a4SGarrett D'Amore
895*698f87a4SGarrett D'Amore static void
post_bk(DECL_ARGS)896*698f87a4SGarrett D'Amore post_bk(DECL_ARGS)
897*698f87a4SGarrett D'Amore {
898*698f87a4SGarrett D'Amore
899*698f87a4SGarrett D'Amore if (MDOC_BODY == n->type)
900*698f87a4SGarrett D'Amore outflags &= ~MMAN_Bk;
901*698f87a4SGarrett D'Amore }
902*698f87a4SGarrett D'Amore
903*698f87a4SGarrett D'Amore static int
pre_bl(DECL_ARGS)904*698f87a4SGarrett D'Amore pre_bl(DECL_ARGS)
905*698f87a4SGarrett D'Amore {
906*698f87a4SGarrett D'Amore size_t icol;
907*698f87a4SGarrett D'Amore
908*698f87a4SGarrett D'Amore /*
909*698f87a4SGarrett D'Amore * print_offs() will increase the -offset to account for
910*698f87a4SGarrett D'Amore * a possible enclosing .It, but any enclosed .It blocks
911*698f87a4SGarrett D'Amore * just nest and do not add up their indentation.
912*698f87a4SGarrett D'Amore */
913*698f87a4SGarrett D'Amore if (n->norm->Bl.offs) {
914*698f87a4SGarrett D'Amore print_offs(n->norm->Bl.offs);
915*698f87a4SGarrett D'Amore Bl_stack[Bl_stack_len++] = 0;
916*698f87a4SGarrett D'Amore }
917*698f87a4SGarrett D'Amore
918*698f87a4SGarrett D'Amore switch (n->norm->Bl.type) {
919*698f87a4SGarrett D'Amore case (LIST_enum):
920*698f87a4SGarrett D'Amore n->norm->Bl.count = 0;
921*698f87a4SGarrett D'Amore return(1);
922*698f87a4SGarrett D'Amore case (LIST_column):
923*698f87a4SGarrett D'Amore break;
924*698f87a4SGarrett D'Amore default:
925*698f87a4SGarrett D'Amore return(1);
926*698f87a4SGarrett D'Amore }
927*698f87a4SGarrett D'Amore
928*698f87a4SGarrett D'Amore print_line(".TS", MMAN_nl);
929*698f87a4SGarrett D'Amore for (icol = 0; icol < n->norm->Bl.ncols; icol++)
930*698f87a4SGarrett D'Amore print_word("l");
931*698f87a4SGarrett D'Amore print_word(".");
932*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
933*698f87a4SGarrett D'Amore return(1);
934*698f87a4SGarrett D'Amore }
935*698f87a4SGarrett D'Amore
936*698f87a4SGarrett D'Amore static void
post_bl(DECL_ARGS)937*698f87a4SGarrett D'Amore post_bl(DECL_ARGS)
938*698f87a4SGarrett D'Amore {
939*698f87a4SGarrett D'Amore
940*698f87a4SGarrett D'Amore switch (n->norm->Bl.type) {
941*698f87a4SGarrett D'Amore case (LIST_column):
942*698f87a4SGarrett D'Amore print_line(".TE", 0);
943*698f87a4SGarrett D'Amore break;
944*698f87a4SGarrett D'Amore case (LIST_enum):
945*698f87a4SGarrett D'Amore n->norm->Bl.count = 0;
946*698f87a4SGarrett D'Amore break;
947*698f87a4SGarrett D'Amore default:
948*698f87a4SGarrett D'Amore break;
949*698f87a4SGarrett D'Amore }
950*698f87a4SGarrett D'Amore
951*698f87a4SGarrett D'Amore if (n->norm->Bl.offs) {
952*698f87a4SGarrett D'Amore print_line(".RE", MMAN_nl);
953*698f87a4SGarrett D'Amore assert(Bl_stack_len);
954*698f87a4SGarrett D'Amore Bl_stack_len--;
955*698f87a4SGarrett D'Amore assert(0 == Bl_stack[Bl_stack_len]);
956*698f87a4SGarrett D'Amore } else {
957*698f87a4SGarrett D'Amore outflags |= MMAN_PP | MMAN_nl;
958*698f87a4SGarrett D'Amore outflags &= ~(MMAN_sp | MMAN_br);
959*698f87a4SGarrett D'Amore }
960*698f87a4SGarrett D'Amore
961*698f87a4SGarrett D'Amore /* Maybe we are inside an enclosing list? */
962*698f87a4SGarrett D'Amore if (NULL != n->parent->next)
963*698f87a4SGarrett D'Amore mid_it();
964*698f87a4SGarrett D'Amore
96595c635efSGarrett D'Amore }
96695c635efSGarrett D'Amore
96795c635efSGarrett D'Amore static int
pre_br(DECL_ARGS)96895c635efSGarrett D'Amore pre_br(DECL_ARGS)
96995c635efSGarrett D'Amore {
97095c635efSGarrett D'Amore
971*698f87a4SGarrett D'Amore outflags |= MMAN_br;
97295c635efSGarrett D'Amore return(0);
97395c635efSGarrett D'Amore }
97495c635efSGarrett D'Amore
97595c635efSGarrett D'Amore static int
pre_bx(DECL_ARGS)97695c635efSGarrett D'Amore pre_bx(DECL_ARGS)
97795c635efSGarrett D'Amore {
97895c635efSGarrett D'Amore
97995c635efSGarrett D'Amore n = n->child;
98095c635efSGarrett D'Amore if (n) {
981*698f87a4SGarrett D'Amore print_word(n->string);
982*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
98395c635efSGarrett D'Amore n = n->next;
98495c635efSGarrett D'Amore }
985*698f87a4SGarrett D'Amore print_word("BSD");
98695c635efSGarrett D'Amore if (NULL == n)
98795c635efSGarrett D'Amore return(0);
988*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
989*698f87a4SGarrett D'Amore print_word("-");
990*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
991*698f87a4SGarrett D'Amore print_word(n->string);
99295c635efSGarrett D'Amore return(0);
99395c635efSGarrett D'Amore }
99495c635efSGarrett D'Amore
99595c635efSGarrett D'Amore static int
pre_dl(DECL_ARGS)99695c635efSGarrett D'Amore pre_dl(DECL_ARGS)
99795c635efSGarrett D'Amore {
99895c635efSGarrett D'Amore
999*698f87a4SGarrett D'Amore print_offs("6n");
100095c635efSGarrett D'Amore return(1);
100195c635efSGarrett D'Amore }
100295c635efSGarrett D'Amore
100395c635efSGarrett D'Amore static void
post_dl(DECL_ARGS)100495c635efSGarrett D'Amore post_dl(DECL_ARGS)
100595c635efSGarrett D'Amore {
100695c635efSGarrett D'Amore
1007*698f87a4SGarrett D'Amore print_line(".RE", MMAN_nl);
1008*698f87a4SGarrett D'Amore
1009*698f87a4SGarrett D'Amore /* Maybe we are inside an enclosing list? */
1010*698f87a4SGarrett D'Amore if (NULL != n->parent->next)
1011*698f87a4SGarrett D'Amore mid_it();
1012*698f87a4SGarrett D'Amore }
1013*698f87a4SGarrett D'Amore
1014*698f87a4SGarrett D'Amore static int
pre_em(DECL_ARGS)1015*698f87a4SGarrett D'Amore pre_em(DECL_ARGS)
1016*698f87a4SGarrett D'Amore {
1017*698f87a4SGarrett D'Amore
1018*698f87a4SGarrett D'Amore font_push('I');
1019*698f87a4SGarrett D'Amore return(1);
1020*698f87a4SGarrett D'Amore }
1021*698f87a4SGarrett D'Amore
1022*698f87a4SGarrett D'Amore static void
post_eo(DECL_ARGS)1023*698f87a4SGarrett D'Amore post_eo(DECL_ARGS)
1024*698f87a4SGarrett D'Amore {
1025*698f87a4SGarrett D'Amore
1026*698f87a4SGarrett D'Amore if (MDOC_HEAD == n->type || MDOC_BODY == n->type)
1027*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1028*698f87a4SGarrett D'Amore }
1029*698f87a4SGarrett D'Amore
1030*698f87a4SGarrett D'Amore static int
pre_fa(DECL_ARGS)1031*698f87a4SGarrett D'Amore pre_fa(DECL_ARGS)
1032*698f87a4SGarrett D'Amore {
1033*698f87a4SGarrett D'Amore int am_Fa;
1034*698f87a4SGarrett D'Amore
1035*698f87a4SGarrett D'Amore am_Fa = MDOC_Fa == n->tok;
1036*698f87a4SGarrett D'Amore
1037*698f87a4SGarrett D'Amore if (am_Fa)
1038*698f87a4SGarrett D'Amore n = n->child;
1039*698f87a4SGarrett D'Amore
1040*698f87a4SGarrett D'Amore while (NULL != n) {
1041*698f87a4SGarrett D'Amore font_push('I');
1042*698f87a4SGarrett D'Amore if (am_Fa || MDOC_SYNPRETTY & n->flags)
1043*698f87a4SGarrett D'Amore outflags |= MMAN_nbrword;
1044*698f87a4SGarrett D'Amore print_node(meta, n);
1045*698f87a4SGarrett D'Amore font_pop();
1046*698f87a4SGarrett D'Amore if (NULL != (n = n->next))
1047*698f87a4SGarrett D'Amore print_word(",");
1048*698f87a4SGarrett D'Amore }
1049*698f87a4SGarrett D'Amore return(0);
1050*698f87a4SGarrett D'Amore }
1051*698f87a4SGarrett D'Amore
1052*698f87a4SGarrett D'Amore static void
post_fa(DECL_ARGS)1053*698f87a4SGarrett D'Amore post_fa(DECL_ARGS)
1054*698f87a4SGarrett D'Amore {
1055*698f87a4SGarrett D'Amore
1056*698f87a4SGarrett D'Amore if (NULL != n->next && MDOC_Fa == n->next->tok)
1057*698f87a4SGarrett D'Amore print_word(",");
1058*698f87a4SGarrett D'Amore }
1059*698f87a4SGarrett D'Amore
1060*698f87a4SGarrett D'Amore static int
pre_fd(DECL_ARGS)1061*698f87a4SGarrett D'Amore pre_fd(DECL_ARGS)
1062*698f87a4SGarrett D'Amore {
1063*698f87a4SGarrett D'Amore
1064*698f87a4SGarrett D'Amore pre_syn(n);
1065*698f87a4SGarrett D'Amore font_push('B');
1066*698f87a4SGarrett D'Amore return(1);
1067*698f87a4SGarrett D'Amore }
1068*698f87a4SGarrett D'Amore
1069*698f87a4SGarrett D'Amore static void
post_fd(DECL_ARGS)1070*698f87a4SGarrett D'Amore post_fd(DECL_ARGS)
1071*698f87a4SGarrett D'Amore {
1072*698f87a4SGarrett D'Amore
1073*698f87a4SGarrett D'Amore font_pop();
1074*698f87a4SGarrett D'Amore outflags |= MMAN_br;
1075*698f87a4SGarrett D'Amore }
1076*698f87a4SGarrett D'Amore
1077*698f87a4SGarrett D'Amore static int
pre_fl(DECL_ARGS)1078*698f87a4SGarrett D'Amore pre_fl(DECL_ARGS)
1079*698f87a4SGarrett D'Amore {
1080*698f87a4SGarrett D'Amore
1081*698f87a4SGarrett D'Amore font_push('B');
1082*698f87a4SGarrett D'Amore print_word("\\-");
1083*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1084*698f87a4SGarrett D'Amore return(1);
1085*698f87a4SGarrett D'Amore }
1086*698f87a4SGarrett D'Amore
1087*698f87a4SGarrett D'Amore static void
post_fl(DECL_ARGS)1088*698f87a4SGarrett D'Amore post_fl(DECL_ARGS)
1089*698f87a4SGarrett D'Amore {
1090*698f87a4SGarrett D'Amore
1091*698f87a4SGarrett D'Amore font_pop();
1092*698f87a4SGarrett D'Amore if (0 == n->nchild && NULL != n->next &&
1093*698f87a4SGarrett D'Amore n->next->line == n->line)
1094*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1095*698f87a4SGarrett D'Amore }
1096*698f87a4SGarrett D'Amore
1097*698f87a4SGarrett D'Amore static int
pre_fn(DECL_ARGS)1098*698f87a4SGarrett D'Amore pre_fn(DECL_ARGS)
1099*698f87a4SGarrett D'Amore {
1100*698f87a4SGarrett D'Amore
1101*698f87a4SGarrett D'Amore pre_syn(n);
1102*698f87a4SGarrett D'Amore
1103*698f87a4SGarrett D'Amore n = n->child;
1104*698f87a4SGarrett D'Amore if (NULL == n)
1105*698f87a4SGarrett D'Amore return(0);
1106*698f87a4SGarrett D'Amore
1107*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags)
1108*698f87a4SGarrett D'Amore print_block(".HP 4n", MMAN_nl);
1109*698f87a4SGarrett D'Amore
1110*698f87a4SGarrett D'Amore font_push('B');
1111*698f87a4SGarrett D'Amore print_node(meta, n);
1112*698f87a4SGarrett D'Amore font_pop();
1113*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1114*698f87a4SGarrett D'Amore print_word("(");
1115*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1116*698f87a4SGarrett D'Amore
1117*698f87a4SGarrett D'Amore n = n->next;
1118*698f87a4SGarrett D'Amore if (NULL != n)
1119*698f87a4SGarrett D'Amore pre_fa(meta, n);
1120*698f87a4SGarrett D'Amore return(0);
1121*698f87a4SGarrett D'Amore }
1122*698f87a4SGarrett D'Amore
1123*698f87a4SGarrett D'Amore static void
post_fn(DECL_ARGS)1124*698f87a4SGarrett D'Amore post_fn(DECL_ARGS)
1125*698f87a4SGarrett D'Amore {
1126*698f87a4SGarrett D'Amore
1127*698f87a4SGarrett D'Amore print_word(")");
1128*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) {
1129*698f87a4SGarrett D'Amore print_word(";");
1130*698f87a4SGarrett D'Amore outflags |= MMAN_PP;
1131*698f87a4SGarrett D'Amore }
1132*698f87a4SGarrett D'Amore }
1133*698f87a4SGarrett D'Amore
1134*698f87a4SGarrett D'Amore static int
pre_fo(DECL_ARGS)1135*698f87a4SGarrett D'Amore pre_fo(DECL_ARGS)
1136*698f87a4SGarrett D'Amore {
1137*698f87a4SGarrett D'Amore
1138*698f87a4SGarrett D'Amore switch (n->type) {
1139*698f87a4SGarrett D'Amore case (MDOC_BLOCK):
1140*698f87a4SGarrett D'Amore pre_syn(n);
1141*698f87a4SGarrett D'Amore break;
1142*698f87a4SGarrett D'Amore case (MDOC_HEAD):
1143*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags)
1144*698f87a4SGarrett D'Amore print_block(".HP 4n", MMAN_nl);
1145*698f87a4SGarrett D'Amore font_push('B');
1146*698f87a4SGarrett D'Amore break;
1147*698f87a4SGarrett D'Amore case (MDOC_BODY):
1148*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1149*698f87a4SGarrett D'Amore print_word("(");
1150*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1151*698f87a4SGarrett D'Amore break;
1152*698f87a4SGarrett D'Amore default:
1153*698f87a4SGarrett D'Amore break;
1154*698f87a4SGarrett D'Amore }
1155*698f87a4SGarrett D'Amore return(1);
1156*698f87a4SGarrett D'Amore }
1157*698f87a4SGarrett D'Amore
1158*698f87a4SGarrett D'Amore static void
post_fo(DECL_ARGS)1159*698f87a4SGarrett D'Amore post_fo(DECL_ARGS)
1160*698f87a4SGarrett D'Amore {
1161*698f87a4SGarrett D'Amore
1162*698f87a4SGarrett D'Amore switch (n->type) {
1163*698f87a4SGarrett D'Amore case (MDOC_HEAD):
1164*698f87a4SGarrett D'Amore font_pop();
1165*698f87a4SGarrett D'Amore break;
1166*698f87a4SGarrett D'Amore case (MDOC_BODY):
1167*698f87a4SGarrett D'Amore post_fn(meta, n);
1168*698f87a4SGarrett D'Amore break;
1169*698f87a4SGarrett D'Amore default:
1170*698f87a4SGarrett D'Amore break;
1171*698f87a4SGarrett D'Amore }
1172*698f87a4SGarrett D'Amore }
1173*698f87a4SGarrett D'Amore
1174*698f87a4SGarrett D'Amore static int
pre_ft(DECL_ARGS)1175*698f87a4SGarrett D'Amore pre_ft(DECL_ARGS)
1176*698f87a4SGarrett D'Amore {
1177*698f87a4SGarrett D'Amore
1178*698f87a4SGarrett D'Amore pre_syn(n);
1179*698f87a4SGarrett D'Amore font_push('I');
1180*698f87a4SGarrett D'Amore return(1);
1181*698f87a4SGarrett D'Amore }
1182*698f87a4SGarrett D'Amore
1183*698f87a4SGarrett D'Amore static int
pre_in(DECL_ARGS)1184*698f87a4SGarrett D'Amore pre_in(DECL_ARGS)
1185*698f87a4SGarrett D'Amore {
1186*698f87a4SGarrett D'Amore
1187*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) {
1188*698f87a4SGarrett D'Amore pre_syn(n);
1189*698f87a4SGarrett D'Amore font_push('B');
1190*698f87a4SGarrett D'Amore print_word("#include <");
1191*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1192*698f87a4SGarrett D'Amore } else {
1193*698f87a4SGarrett D'Amore print_word("<");
1194*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1195*698f87a4SGarrett D'Amore font_push('I');
1196*698f87a4SGarrett D'Amore }
1197*698f87a4SGarrett D'Amore return(1);
1198*698f87a4SGarrett D'Amore }
1199*698f87a4SGarrett D'Amore
1200*698f87a4SGarrett D'Amore static void
post_in(DECL_ARGS)1201*698f87a4SGarrett D'Amore post_in(DECL_ARGS)
1202*698f87a4SGarrett D'Amore {
1203*698f87a4SGarrett D'Amore
1204*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) {
1205*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1206*698f87a4SGarrett D'Amore print_word(">");
1207*698f87a4SGarrett D'Amore font_pop();
1208*698f87a4SGarrett D'Amore outflags |= MMAN_br;
1209*698f87a4SGarrett D'Amore } else {
1210*698f87a4SGarrett D'Amore font_pop();
1211*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1212*698f87a4SGarrett D'Amore print_word(">");
1213*698f87a4SGarrett D'Amore }
121495c635efSGarrett D'Amore }
121595c635efSGarrett D'Amore
121695c635efSGarrett D'Amore static int
pre_it(DECL_ARGS)121795c635efSGarrett D'Amore pre_it(DECL_ARGS)
121895c635efSGarrett D'Amore {
121995c635efSGarrett D'Amore const struct mdoc_node *bln;
122095c635efSGarrett D'Amore
1221*698f87a4SGarrett D'Amore switch (n->type) {
1222*698f87a4SGarrett D'Amore case (MDOC_HEAD):
1223*698f87a4SGarrett D'Amore outflags |= MMAN_PP | MMAN_nl;
1224*698f87a4SGarrett D'Amore bln = n->parent->parent;
1225*698f87a4SGarrett D'Amore if (0 == bln->norm->Bl.comp ||
1226*698f87a4SGarrett D'Amore (NULL == n->parent->prev &&
1227*698f87a4SGarrett D'Amore NULL == bln->parent->prev))
1228*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
1229*698f87a4SGarrett D'Amore outflags &= ~MMAN_br;
123095c635efSGarrett D'Amore switch (bln->norm->Bl.type) {
1231*698f87a4SGarrett D'Amore case (LIST_item):
1232*698f87a4SGarrett D'Amore return(0);
1233*698f87a4SGarrett D'Amore case (LIST_inset):
1234*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1235*698f87a4SGarrett D'Amore case (LIST_diag):
1236*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1237*698f87a4SGarrett D'Amore case (LIST_ohang):
1238*698f87a4SGarrett D'Amore if (bln->norm->Bl.type == LIST_diag)
1239*698f87a4SGarrett D'Amore print_line(".B \"", 0);
1240*698f87a4SGarrett D'Amore else
1241*698f87a4SGarrett D'Amore print_line(".R \"", 0);
1242*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1243*698f87a4SGarrett D'Amore return(1);
124495c635efSGarrett D'Amore case (LIST_bullet):
1245*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1246*698f87a4SGarrett D'Amore case (LIST_dash):
1247*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1248*698f87a4SGarrett D'Amore case (LIST_hyphen):
1249*698f87a4SGarrett D'Amore print_width(bln->norm->Bl.width, NULL, 0);
1250*698f87a4SGarrett D'Amore TPremain = 0;
1251*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
1252*698f87a4SGarrett D'Amore font_push('B');
1253*698f87a4SGarrett D'Amore if (LIST_bullet == bln->norm->Bl.type)
1254*698f87a4SGarrett D'Amore print_word("o");
1255*698f87a4SGarrett D'Amore else
1256*698f87a4SGarrett D'Amore print_word("-");
1257*698f87a4SGarrett D'Amore font_pop();
1258*698f87a4SGarrett D'Amore break;
1259*698f87a4SGarrett D'Amore case (LIST_enum):
1260*698f87a4SGarrett D'Amore print_width(bln->norm->Bl.width, NULL, 0);
1261*698f87a4SGarrett D'Amore TPremain = 0;
1262*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
1263*698f87a4SGarrett D'Amore print_count(&bln->norm->Bl.count);
1264*698f87a4SGarrett D'Amore break;
1265*698f87a4SGarrett D'Amore case (LIST_hang):
1266*698f87a4SGarrett D'Amore print_width(bln->norm->Bl.width, n->child, 6);
1267*698f87a4SGarrett D'Amore TPremain = 0;
1268*698f87a4SGarrett D'Amore break;
1269*698f87a4SGarrett D'Amore case (LIST_tag):
1270*698f87a4SGarrett D'Amore print_width(bln->norm->Bl.width, n->child, 0);
1271*698f87a4SGarrett D'Amore putchar('\n');
1272*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1273*698f87a4SGarrett D'Amore return(1);
1274*698f87a4SGarrett D'Amore default:
1275*698f87a4SGarrett D'Amore return(1);
1276*698f87a4SGarrett D'Amore }
1277*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
1278*698f87a4SGarrett D'Amore default:
1279*698f87a4SGarrett D'Amore break;
1280*698f87a4SGarrett D'Amore }
1281*698f87a4SGarrett D'Amore return(1);
1282*698f87a4SGarrett D'Amore }
1283*698f87a4SGarrett D'Amore
1284*698f87a4SGarrett D'Amore /*
1285*698f87a4SGarrett D'Amore * This function is called after closing out an indented block.
1286*698f87a4SGarrett D'Amore * If we are inside an enclosing list, restore its indentation.
1287*698f87a4SGarrett D'Amore */
1288*698f87a4SGarrett D'Amore static void
mid_it(void)1289*698f87a4SGarrett D'Amore mid_it(void)
1290*698f87a4SGarrett D'Amore {
1291*698f87a4SGarrett D'Amore char buf[24];
1292*698f87a4SGarrett D'Amore
1293*698f87a4SGarrett D'Amore /* Nothing to do outside a list. */
1294*698f87a4SGarrett D'Amore if (0 == Bl_stack_len || 0 == Bl_stack[Bl_stack_len - 1])
1295*698f87a4SGarrett D'Amore return;
1296*698f87a4SGarrett D'Amore
1297*698f87a4SGarrett D'Amore /* The indentation has already been set up. */
1298*698f87a4SGarrett D'Amore if (Bl_stack_post[Bl_stack_len - 1])
1299*698f87a4SGarrett D'Amore return;
1300*698f87a4SGarrett D'Amore
1301*698f87a4SGarrett D'Amore /* Restore the indentation of the enclosing list. */
1302*698f87a4SGarrett D'Amore print_line(".RS", MMAN_Bk_susp);
1303*698f87a4SGarrett D'Amore snprintf(buf, sizeof(buf), "%zun", Bl_stack[Bl_stack_len - 1]);
1304*698f87a4SGarrett D'Amore print_word(buf);
1305*698f87a4SGarrett D'Amore
1306*698f87a4SGarrett D'Amore /* Remeber to close out this .RS block later. */
1307*698f87a4SGarrett D'Amore Bl_stack_post[Bl_stack_len - 1] = 1;
1308*698f87a4SGarrett D'Amore }
1309*698f87a4SGarrett D'Amore
1310*698f87a4SGarrett D'Amore static void
post_it(DECL_ARGS)1311*698f87a4SGarrett D'Amore post_it(DECL_ARGS)
1312*698f87a4SGarrett D'Amore {
1313*698f87a4SGarrett D'Amore const struct mdoc_node *bln;
1314*698f87a4SGarrett D'Amore
1315*698f87a4SGarrett D'Amore bln = n->parent->parent;
1316*698f87a4SGarrett D'Amore
1317*698f87a4SGarrett D'Amore switch (n->type) {
1318*698f87a4SGarrett D'Amore case (MDOC_HEAD):
1319*698f87a4SGarrett D'Amore switch (bln->norm->Bl.type) {
1320*698f87a4SGarrett D'Amore case (LIST_diag):
1321*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1322*698f87a4SGarrett D'Amore print_word("\\ ");
1323*698f87a4SGarrett D'Amore break;
1324*698f87a4SGarrett D'Amore case (LIST_ohang):
1325*698f87a4SGarrett D'Amore outflags |= MMAN_br;
132695c635efSGarrett D'Amore break;
132795c635efSGarrett D'Amore default:
132895c635efSGarrett D'Amore break;
132995c635efSGarrett D'Amore }
1330*698f87a4SGarrett D'Amore break;
1331*698f87a4SGarrett D'Amore case (MDOC_BODY):
1332*698f87a4SGarrett D'Amore switch (bln->norm->Bl.type) {
1333*698f87a4SGarrett D'Amore case (LIST_bullet):
1334*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1335*698f87a4SGarrett D'Amore case (LIST_dash):
1336*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1337*698f87a4SGarrett D'Amore case (LIST_hyphen):
1338*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1339*698f87a4SGarrett D'Amore case (LIST_enum):
1340*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1341*698f87a4SGarrett D'Amore case (LIST_hang):
1342*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1343*698f87a4SGarrett D'Amore case (LIST_tag):
1344*698f87a4SGarrett D'Amore assert(Bl_stack_len);
1345*698f87a4SGarrett D'Amore Bl_stack[--Bl_stack_len] = 0;
1346*698f87a4SGarrett D'Amore
1347*698f87a4SGarrett D'Amore /*
1348*698f87a4SGarrett D'Amore * Our indentation had to be restored
1349*698f87a4SGarrett D'Amore * after a child display or child list.
1350*698f87a4SGarrett D'Amore * Close out that indentation block now.
1351*698f87a4SGarrett D'Amore */
1352*698f87a4SGarrett D'Amore if (Bl_stack_post[Bl_stack_len]) {
1353*698f87a4SGarrett D'Amore print_line(".RE", MMAN_nl);
1354*698f87a4SGarrett D'Amore Bl_stack_post[Bl_stack_len] = 0;
135595c635efSGarrett D'Amore }
1356*698f87a4SGarrett D'Amore break;
1357*698f87a4SGarrett D'Amore case (LIST_column):
1358*698f87a4SGarrett D'Amore if (NULL != n->next) {
1359*698f87a4SGarrett D'Amore putchar('\t');
1360*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1361*698f87a4SGarrett D'Amore }
1362*698f87a4SGarrett D'Amore break;
1363*698f87a4SGarrett D'Amore default:
1364*698f87a4SGarrett D'Amore break;
1365*698f87a4SGarrett D'Amore }
1366*698f87a4SGarrett D'Amore break;
1367*698f87a4SGarrett D'Amore default:
1368*698f87a4SGarrett D'Amore break;
1369*698f87a4SGarrett D'Amore }
1370*698f87a4SGarrett D'Amore }
1371*698f87a4SGarrett D'Amore
1372*698f87a4SGarrett D'Amore static void
post_lb(DECL_ARGS)1373*698f87a4SGarrett D'Amore post_lb(DECL_ARGS)
1374*698f87a4SGarrett D'Amore {
1375*698f87a4SGarrett D'Amore
1376*698f87a4SGarrett D'Amore if (SEC_LIBRARY == n->sec)
1377*698f87a4SGarrett D'Amore outflags |= MMAN_br;
1378*698f87a4SGarrett D'Amore }
1379*698f87a4SGarrett D'Amore
1380*698f87a4SGarrett D'Amore static int
pre_lk(DECL_ARGS)1381*698f87a4SGarrett D'Amore pre_lk(DECL_ARGS)
1382*698f87a4SGarrett D'Amore {
1383*698f87a4SGarrett D'Amore const struct mdoc_node *link, *descr;
1384*698f87a4SGarrett D'Amore
1385*698f87a4SGarrett D'Amore if (NULL == (link = n->child))
1386*698f87a4SGarrett D'Amore return(0);
1387*698f87a4SGarrett D'Amore
1388*698f87a4SGarrett D'Amore if (NULL != (descr = link->next)) {
1389*698f87a4SGarrett D'Amore font_push('I');
1390*698f87a4SGarrett D'Amore while (NULL != descr) {
1391*698f87a4SGarrett D'Amore print_word(descr->string);
1392*698f87a4SGarrett D'Amore descr = descr->next;
1393*698f87a4SGarrett D'Amore }
1394*698f87a4SGarrett D'Amore print_word(":");
1395*698f87a4SGarrett D'Amore font_pop();
1396*698f87a4SGarrett D'Amore }
1397*698f87a4SGarrett D'Amore
1398*698f87a4SGarrett D'Amore font_push('B');
1399*698f87a4SGarrett D'Amore print_word(link->string);
1400*698f87a4SGarrett D'Amore font_pop();
1401*698f87a4SGarrett D'Amore return(0);
1402*698f87a4SGarrett D'Amore }
1403*698f87a4SGarrett D'Amore
1404*698f87a4SGarrett D'Amore static int
pre_li(DECL_ARGS)1405*698f87a4SGarrett D'Amore pre_li(DECL_ARGS)
1406*698f87a4SGarrett D'Amore {
1407*698f87a4SGarrett D'Amore
1408*698f87a4SGarrett D'Amore font_push('R');
140995c635efSGarrett D'Amore return(1);
141095c635efSGarrett D'Amore }
141195c635efSGarrett D'Amore
141295c635efSGarrett D'Amore static int
pre_nm(DECL_ARGS)141395c635efSGarrett D'Amore pre_nm(DECL_ARGS)
141495c635efSGarrett D'Amore {
1415*698f87a4SGarrett D'Amore char *name;
141695c635efSGarrett D'Amore
1417*698f87a4SGarrett D'Amore if (MDOC_BLOCK == n->type) {
1418*698f87a4SGarrett D'Amore outflags |= MMAN_Bk;
1419*698f87a4SGarrett D'Amore pre_syn(n);
1420*698f87a4SGarrett D'Amore }
142195c635efSGarrett D'Amore if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
142295c635efSGarrett D'Amore return(1);
1423*698f87a4SGarrett D'Amore name = n->child ? n->child->string : meta->name;
1424*698f87a4SGarrett D'Amore if (NULL == name)
1425*698f87a4SGarrett D'Amore return(0);
1426*698f87a4SGarrett D'Amore if (MDOC_HEAD == n->type) {
1427*698f87a4SGarrett D'Amore if (NULL == n->parent->prev)
1428*698f87a4SGarrett D'Amore outflags |= MMAN_sp;
1429*698f87a4SGarrett D'Amore print_block(".HP", 0);
1430*698f87a4SGarrett D'Amore printf(" %zun", strlen(name) + 1);
1431*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
1432*698f87a4SGarrett D'Amore }
1433*698f87a4SGarrett D'Amore font_push('B');
143495c635efSGarrett D'Amore if (NULL == n->child)
1435*698f87a4SGarrett D'Amore print_word(meta->name);
143695c635efSGarrett D'Amore return(1);
143795c635efSGarrett D'Amore }
143895c635efSGarrett D'Amore
143995c635efSGarrett D'Amore static void
post_nm(DECL_ARGS)144095c635efSGarrett D'Amore post_nm(DECL_ARGS)
144195c635efSGarrett D'Amore {
144295c635efSGarrett D'Amore
1443*698f87a4SGarrett D'Amore switch (n->type) {
1444*698f87a4SGarrett D'Amore case (MDOC_BLOCK):
1445*698f87a4SGarrett D'Amore outflags &= ~MMAN_Bk;
1446*698f87a4SGarrett D'Amore break;
1447*698f87a4SGarrett D'Amore case (MDOC_HEAD):
1448*698f87a4SGarrett D'Amore /* FALLTHROUGH */
1449*698f87a4SGarrett D'Amore case (MDOC_ELEM):
1450*698f87a4SGarrett D'Amore font_pop();
1451*698f87a4SGarrett D'Amore break;
1452*698f87a4SGarrett D'Amore default:
1453*698f87a4SGarrett D'Amore break;
1454*698f87a4SGarrett D'Amore }
1455*698f87a4SGarrett D'Amore }
1456*698f87a4SGarrett D'Amore
1457*698f87a4SGarrett D'Amore static int
pre_no(DECL_ARGS)1458*698f87a4SGarrett D'Amore pre_no(DECL_ARGS)
1459*698f87a4SGarrett D'Amore {
1460*698f87a4SGarrett D'Amore
1461*698f87a4SGarrett D'Amore outflags |= MMAN_spc_force;
1462*698f87a4SGarrett D'Amore return(1);
146395c635efSGarrett D'Amore }
146495c635efSGarrett D'Amore
146595c635efSGarrett D'Amore static int
pre_ns(DECL_ARGS)146695c635efSGarrett D'Amore pre_ns(DECL_ARGS)
146795c635efSGarrett D'Amore {
146895c635efSGarrett D'Amore
1469*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
147095c635efSGarrett D'Amore return(0);
147195c635efSGarrett D'Amore }
147295c635efSGarrett D'Amore
147395c635efSGarrett D'Amore static void
post_pf(DECL_ARGS)147495c635efSGarrett D'Amore post_pf(DECL_ARGS)
147595c635efSGarrett D'Amore {
147695c635efSGarrett D'Amore
1477*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
147895c635efSGarrett D'Amore }
147995c635efSGarrett D'Amore
148095c635efSGarrett D'Amore static int
pre_pp(DECL_ARGS)148195c635efSGarrett D'Amore pre_pp(DECL_ARGS)
148295c635efSGarrett D'Amore {
148395c635efSGarrett D'Amore
1484*698f87a4SGarrett D'Amore if (MDOC_It != n->parent->tok)
1485*698f87a4SGarrett D'Amore outflags |= MMAN_PP;
1486*698f87a4SGarrett D'Amore outflags |= MMAN_sp | MMAN_nl;
1487*698f87a4SGarrett D'Amore outflags &= ~MMAN_br;
1488*698f87a4SGarrett D'Amore return(0);
1489*698f87a4SGarrett D'Amore }
1490*698f87a4SGarrett D'Amore
1491*698f87a4SGarrett D'Amore static int
pre_rs(DECL_ARGS)1492*698f87a4SGarrett D'Amore pre_rs(DECL_ARGS)
1493*698f87a4SGarrett D'Amore {
1494*698f87a4SGarrett D'Amore
1495*698f87a4SGarrett D'Amore if (SEC_SEE_ALSO == n->sec) {
1496*698f87a4SGarrett D'Amore outflags |= MMAN_PP | MMAN_sp | MMAN_nl;
1497*698f87a4SGarrett D'Amore outflags &= ~MMAN_br;
1498*698f87a4SGarrett D'Amore }
149995c635efSGarrett D'Amore return(1);
150095c635efSGarrett D'Amore }
150195c635efSGarrett D'Amore
150295c635efSGarrett D'Amore static int
pre_sm(DECL_ARGS)1503*698f87a4SGarrett D'Amore pre_sm(DECL_ARGS)
1504*698f87a4SGarrett D'Amore {
1505*698f87a4SGarrett D'Amore
1506*698f87a4SGarrett D'Amore assert(n->child && MDOC_TEXT == n->child->type);
1507*698f87a4SGarrett D'Amore if (0 == strcmp("on", n->child->string))
1508*698f87a4SGarrett D'Amore outflags |= MMAN_Sm | MMAN_spc;
1509*698f87a4SGarrett D'Amore else
1510*698f87a4SGarrett D'Amore outflags &= ~MMAN_Sm;
1511*698f87a4SGarrett D'Amore return(0);
1512*698f87a4SGarrett D'Amore }
1513*698f87a4SGarrett D'Amore
1514*698f87a4SGarrett D'Amore static int
pre_sp(DECL_ARGS)151595c635efSGarrett D'Amore pre_sp(DECL_ARGS)
151695c635efSGarrett D'Amore {
151795c635efSGarrett D'Amore
1518*698f87a4SGarrett D'Amore if (MMAN_PP & outflags) {
1519*698f87a4SGarrett D'Amore outflags &= ~MMAN_PP;
1520*698f87a4SGarrett D'Amore print_line(".PP", 0);
1521*698f87a4SGarrett D'Amore } else
1522*698f87a4SGarrett D'Amore print_line(".sp", 0);
152395c635efSGarrett D'Amore return(1);
152495c635efSGarrett D'Amore }
152595c635efSGarrett D'Amore
152695c635efSGarrett D'Amore static void
post_sp(DECL_ARGS)152795c635efSGarrett D'Amore post_sp(DECL_ARGS)
152895c635efSGarrett D'Amore {
152995c635efSGarrett D'Amore
1530*698f87a4SGarrett D'Amore outflags |= MMAN_nl;
1531*698f87a4SGarrett D'Amore }
1532*698f87a4SGarrett D'Amore
1533*698f87a4SGarrett D'Amore static int
pre_sy(DECL_ARGS)1534*698f87a4SGarrett D'Amore pre_sy(DECL_ARGS)
1535*698f87a4SGarrett D'Amore {
1536*698f87a4SGarrett D'Amore
1537*698f87a4SGarrett D'Amore font_push('B');
1538*698f87a4SGarrett D'Amore return(1);
1539*698f87a4SGarrett D'Amore }
1540*698f87a4SGarrett D'Amore
1541*698f87a4SGarrett D'Amore static int
pre_vt(DECL_ARGS)1542*698f87a4SGarrett D'Amore pre_vt(DECL_ARGS)
1543*698f87a4SGarrett D'Amore {
1544*698f87a4SGarrett D'Amore
1545*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) {
1546*698f87a4SGarrett D'Amore switch (n->type) {
1547*698f87a4SGarrett D'Amore case (MDOC_BLOCK):
1548*698f87a4SGarrett D'Amore pre_syn(n);
1549*698f87a4SGarrett D'Amore return(1);
1550*698f87a4SGarrett D'Amore case (MDOC_BODY):
1551*698f87a4SGarrett D'Amore break;
1552*698f87a4SGarrett D'Amore default:
1553*698f87a4SGarrett D'Amore return(0);
1554*698f87a4SGarrett D'Amore }
1555*698f87a4SGarrett D'Amore }
1556*698f87a4SGarrett D'Amore font_push('I');
1557*698f87a4SGarrett D'Amore return(1);
1558*698f87a4SGarrett D'Amore }
1559*698f87a4SGarrett D'Amore
1560*698f87a4SGarrett D'Amore static void
post_vt(DECL_ARGS)1561*698f87a4SGarrett D'Amore post_vt(DECL_ARGS)
1562*698f87a4SGarrett D'Amore {
1563*698f87a4SGarrett D'Amore
1564*698f87a4SGarrett D'Amore if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type)
1565*698f87a4SGarrett D'Amore return;
1566*698f87a4SGarrett D'Amore font_pop();
156795c635efSGarrett D'Amore }
156895c635efSGarrett D'Amore
156995c635efSGarrett D'Amore static int
pre_xr(DECL_ARGS)157095c635efSGarrett D'Amore pre_xr(DECL_ARGS)
157195c635efSGarrett D'Amore {
157295c635efSGarrett D'Amore
157395c635efSGarrett D'Amore n = n->child;
157495c635efSGarrett D'Amore if (NULL == n)
157595c635efSGarrett D'Amore return(0);
1576*698f87a4SGarrett D'Amore print_node(meta, n);
157795c635efSGarrett D'Amore n = n->next;
157895c635efSGarrett D'Amore if (NULL == n)
157995c635efSGarrett D'Amore return(0);
1580*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1581*698f87a4SGarrett D'Amore print_word("(");
1582*698f87a4SGarrett D'Amore print_node(meta, n);
1583*698f87a4SGarrett D'Amore print_word(")");
158495c635efSGarrett D'Amore return(0);
158595c635efSGarrett D'Amore }
158695c635efSGarrett D'Amore
158795c635efSGarrett D'Amore static int
pre_ux(DECL_ARGS)158895c635efSGarrett D'Amore pre_ux(DECL_ARGS)
158995c635efSGarrett D'Amore {
159095c635efSGarrett D'Amore
1591*698f87a4SGarrett D'Amore print_word(manacts[n->tok].prefix);
159295c635efSGarrett D'Amore if (NULL == n->child)
159395c635efSGarrett D'Amore return(0);
1594*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
1595*698f87a4SGarrett D'Amore print_word("\\ ");
1596*698f87a4SGarrett D'Amore outflags &= ~MMAN_spc;
159795c635efSGarrett D'Amore return(1);
159895c635efSGarrett D'Amore }
1599