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