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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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