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