1*95c635efSGarrett D'Amore /* $Id: mdoc_term.c,v 1.238 2011/11/13 13:15:14 schwarze Exp $ */ 2*95c635efSGarrett D'Amore /* 3*95c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*95c635efSGarrett D'Amore * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> 5*95c635efSGarrett D'Amore * 6*95c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 7*95c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 8*95c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 9*95c635efSGarrett D'Amore * 10*95c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11*95c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12*95c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13*95c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14*95c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15*95c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16*95c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17*95c635efSGarrett D'Amore */ 18*95c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 19*95c635efSGarrett D'Amore #include "config.h" 20*95c635efSGarrett D'Amore #endif 21*95c635efSGarrett D'Amore 22*95c635efSGarrett D'Amore #include <sys/types.h> 23*95c635efSGarrett D'Amore 24*95c635efSGarrett D'Amore #include <assert.h> 25*95c635efSGarrett D'Amore #include <ctype.h> 26*95c635efSGarrett D'Amore #include <stdint.h> 27*95c635efSGarrett D'Amore #include <stdio.h> 28*95c635efSGarrett D'Amore #include <stdlib.h> 29*95c635efSGarrett D'Amore #include <string.h> 30*95c635efSGarrett D'Amore 31*95c635efSGarrett D'Amore #include "mandoc.h" 32*95c635efSGarrett D'Amore #include "out.h" 33*95c635efSGarrett D'Amore #include "term.h" 34*95c635efSGarrett D'Amore #include "mdoc.h" 35*95c635efSGarrett D'Amore #include "main.h" 36*95c635efSGarrett D'Amore 37*95c635efSGarrett D'Amore struct termpair { 38*95c635efSGarrett D'Amore struct termpair *ppair; 39*95c635efSGarrett D'Amore int count; 40*95c635efSGarrett D'Amore }; 41*95c635efSGarrett D'Amore 42*95c635efSGarrett D'Amore #define DECL_ARGS struct termp *p, \ 43*95c635efSGarrett D'Amore struct termpair *pair, \ 44*95c635efSGarrett D'Amore const struct mdoc_meta *m, \ 45*95c635efSGarrett D'Amore const struct mdoc_node *n 46*95c635efSGarrett D'Amore 47*95c635efSGarrett D'Amore struct termact { 48*95c635efSGarrett D'Amore int (*pre)(DECL_ARGS); 49*95c635efSGarrett D'Amore void (*post)(DECL_ARGS); 50*95c635efSGarrett D'Amore }; 51*95c635efSGarrett D'Amore 52*95c635efSGarrett D'Amore static size_t a2width(const struct termp *, const char *); 53*95c635efSGarrett D'Amore static size_t a2height(const struct termp *, const char *); 54*95c635efSGarrett D'Amore static size_t a2offs(const struct termp *, const char *); 55*95c635efSGarrett D'Amore 56*95c635efSGarrett D'Amore static void print_bvspace(struct termp *, 57*95c635efSGarrett D'Amore const struct mdoc_node *, 58*95c635efSGarrett D'Amore const struct mdoc_node *); 59*95c635efSGarrett D'Amore static void print_mdoc_node(DECL_ARGS); 60*95c635efSGarrett D'Amore static void print_mdoc_nodelist(DECL_ARGS); 61*95c635efSGarrett D'Amore static void print_mdoc_head(struct termp *, const void *); 62*95c635efSGarrett D'Amore static void print_mdoc_foot(struct termp *, const void *); 63*95c635efSGarrett D'Amore static void synopsis_pre(struct termp *, 64*95c635efSGarrett D'Amore const struct mdoc_node *); 65*95c635efSGarrett D'Amore 66*95c635efSGarrett D'Amore static void termp____post(DECL_ARGS); 67*95c635efSGarrett D'Amore static void termp__t_post(DECL_ARGS); 68*95c635efSGarrett D'Amore static void termp_an_post(DECL_ARGS); 69*95c635efSGarrett D'Amore static void termp_bd_post(DECL_ARGS); 70*95c635efSGarrett D'Amore static void termp_bk_post(DECL_ARGS); 71*95c635efSGarrett D'Amore static void termp_bl_post(DECL_ARGS); 72*95c635efSGarrett D'Amore static void termp_d1_post(DECL_ARGS); 73*95c635efSGarrett D'Amore static void termp_fo_post(DECL_ARGS); 74*95c635efSGarrett D'Amore static void termp_in_post(DECL_ARGS); 75*95c635efSGarrett D'Amore static void termp_it_post(DECL_ARGS); 76*95c635efSGarrett D'Amore static void termp_lb_post(DECL_ARGS); 77*95c635efSGarrett D'Amore static void termp_nm_post(DECL_ARGS); 78*95c635efSGarrett D'Amore static void termp_pf_post(DECL_ARGS); 79*95c635efSGarrett D'Amore static void termp_quote_post(DECL_ARGS); 80*95c635efSGarrett D'Amore static void termp_sh_post(DECL_ARGS); 81*95c635efSGarrett D'Amore static void termp_ss_post(DECL_ARGS); 82*95c635efSGarrett D'Amore 83*95c635efSGarrett D'Amore static int termp__a_pre(DECL_ARGS); 84*95c635efSGarrett D'Amore static int termp__t_pre(DECL_ARGS); 85*95c635efSGarrett D'Amore static int termp_an_pre(DECL_ARGS); 86*95c635efSGarrett D'Amore static int termp_ap_pre(DECL_ARGS); 87*95c635efSGarrett D'Amore static int termp_bd_pre(DECL_ARGS); 88*95c635efSGarrett D'Amore static int termp_bf_pre(DECL_ARGS); 89*95c635efSGarrett D'Amore static int termp_bk_pre(DECL_ARGS); 90*95c635efSGarrett D'Amore static int termp_bl_pre(DECL_ARGS); 91*95c635efSGarrett D'Amore static int termp_bold_pre(DECL_ARGS); 92*95c635efSGarrett D'Amore static int termp_bt_pre(DECL_ARGS); 93*95c635efSGarrett D'Amore static int termp_bx_pre(DECL_ARGS); 94*95c635efSGarrett D'Amore static int termp_cd_pre(DECL_ARGS); 95*95c635efSGarrett D'Amore static int termp_d1_pre(DECL_ARGS); 96*95c635efSGarrett D'Amore static int termp_ex_pre(DECL_ARGS); 97*95c635efSGarrett D'Amore static int termp_fa_pre(DECL_ARGS); 98*95c635efSGarrett D'Amore static int termp_fd_pre(DECL_ARGS); 99*95c635efSGarrett D'Amore static int termp_fl_pre(DECL_ARGS); 100*95c635efSGarrett D'Amore static int termp_fn_pre(DECL_ARGS); 101*95c635efSGarrett D'Amore static int termp_fo_pre(DECL_ARGS); 102*95c635efSGarrett D'Amore static int termp_ft_pre(DECL_ARGS); 103*95c635efSGarrett D'Amore static int termp_igndelim_pre(DECL_ARGS); 104*95c635efSGarrett D'Amore static int termp_in_pre(DECL_ARGS); 105*95c635efSGarrett D'Amore static int termp_it_pre(DECL_ARGS); 106*95c635efSGarrett D'Amore static int termp_li_pre(DECL_ARGS); 107*95c635efSGarrett D'Amore static int termp_lk_pre(DECL_ARGS); 108*95c635efSGarrett D'Amore static int termp_nd_pre(DECL_ARGS); 109*95c635efSGarrett D'Amore static int termp_nm_pre(DECL_ARGS); 110*95c635efSGarrett D'Amore static int termp_ns_pre(DECL_ARGS); 111*95c635efSGarrett D'Amore static int termp_quote_pre(DECL_ARGS); 112*95c635efSGarrett D'Amore static int termp_rs_pre(DECL_ARGS); 113*95c635efSGarrett D'Amore static int termp_rv_pre(DECL_ARGS); 114*95c635efSGarrett D'Amore static int termp_sh_pre(DECL_ARGS); 115*95c635efSGarrett D'Amore static int termp_sm_pre(DECL_ARGS); 116*95c635efSGarrett D'Amore static int termp_sp_pre(DECL_ARGS); 117*95c635efSGarrett D'Amore static int termp_ss_pre(DECL_ARGS); 118*95c635efSGarrett D'Amore static int termp_under_pre(DECL_ARGS); 119*95c635efSGarrett D'Amore static int termp_ud_pre(DECL_ARGS); 120*95c635efSGarrett D'Amore static int termp_vt_pre(DECL_ARGS); 121*95c635efSGarrett D'Amore static int termp_xr_pre(DECL_ARGS); 122*95c635efSGarrett D'Amore static int termp_xx_pre(DECL_ARGS); 123*95c635efSGarrett D'Amore 124*95c635efSGarrett D'Amore static const struct termact termacts[MDOC_MAX] = { 125*95c635efSGarrett D'Amore { termp_ap_pre, NULL }, /* Ap */ 126*95c635efSGarrett D'Amore { NULL, NULL }, /* Dd */ 127*95c635efSGarrett D'Amore { NULL, NULL }, /* Dt */ 128*95c635efSGarrett D'Amore { NULL, NULL }, /* Os */ 129*95c635efSGarrett D'Amore { termp_sh_pre, termp_sh_post }, /* Sh */ 130*95c635efSGarrett D'Amore { termp_ss_pre, termp_ss_post }, /* Ss */ 131*95c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Pp */ 132*95c635efSGarrett D'Amore { termp_d1_pre, termp_d1_post }, /* D1 */ 133*95c635efSGarrett D'Amore { termp_d1_pre, termp_d1_post }, /* Dl */ 134*95c635efSGarrett D'Amore { termp_bd_pre, termp_bd_post }, /* Bd */ 135*95c635efSGarrett D'Amore { NULL, NULL }, /* Ed */ 136*95c635efSGarrett D'Amore { termp_bl_pre, termp_bl_post }, /* Bl */ 137*95c635efSGarrett D'Amore { NULL, NULL }, /* El */ 138*95c635efSGarrett D'Amore { termp_it_pre, termp_it_post }, /* It */ 139*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ad */ 140*95c635efSGarrett D'Amore { termp_an_pre, termp_an_post }, /* An */ 141*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ar */ 142*95c635efSGarrett D'Amore { termp_cd_pre, NULL }, /* Cd */ 143*95c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Cm */ 144*95c635efSGarrett D'Amore { NULL, NULL }, /* Dv */ 145*95c635efSGarrett D'Amore { NULL, NULL }, /* Er */ 146*95c635efSGarrett D'Amore { NULL, NULL }, /* Ev */ 147*95c635efSGarrett D'Amore { termp_ex_pre, NULL }, /* Ex */ 148*95c635efSGarrett D'Amore { termp_fa_pre, NULL }, /* Fa */ 149*95c635efSGarrett D'Amore { termp_fd_pre, NULL }, /* Fd */ 150*95c635efSGarrett D'Amore { termp_fl_pre, NULL }, /* Fl */ 151*95c635efSGarrett D'Amore { termp_fn_pre, NULL }, /* Fn */ 152*95c635efSGarrett D'Amore { termp_ft_pre, NULL }, /* Ft */ 153*95c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ic */ 154*95c635efSGarrett D'Amore { termp_in_pre, termp_in_post }, /* In */ 155*95c635efSGarrett D'Amore { termp_li_pre, NULL }, /* Li */ 156*95c635efSGarrett D'Amore { termp_nd_pre, NULL }, /* Nd */ 157*95c635efSGarrett D'Amore { termp_nm_pre, termp_nm_post }, /* Nm */ 158*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Op */ 159*95c635efSGarrett D'Amore { NULL, NULL }, /* Ot */ 160*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Pa */ 161*95c635efSGarrett D'Amore { termp_rv_pre, NULL }, /* Rv */ 162*95c635efSGarrett D'Amore { NULL, NULL }, /* St */ 163*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Va */ 164*95c635efSGarrett D'Amore { termp_vt_pre, NULL }, /* Vt */ 165*95c635efSGarrett D'Amore { termp_xr_pre, NULL }, /* Xr */ 166*95c635efSGarrett D'Amore { termp__a_pre, termp____post }, /* %A */ 167*95c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %B */ 168*95c635efSGarrett D'Amore { NULL, termp____post }, /* %D */ 169*95c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %I */ 170*95c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %J */ 171*95c635efSGarrett D'Amore { NULL, termp____post }, /* %N */ 172*95c635efSGarrett D'Amore { NULL, termp____post }, /* %O */ 173*95c635efSGarrett D'Amore { NULL, termp____post }, /* %P */ 174*95c635efSGarrett D'Amore { NULL, termp____post }, /* %R */ 175*95c635efSGarrett D'Amore { termp__t_pre, termp__t_post }, /* %T */ 176*95c635efSGarrett D'Amore { NULL, termp____post }, /* %V */ 177*95c635efSGarrett D'Amore { NULL, NULL }, /* Ac */ 178*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ao */ 179*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Aq */ 180*95c635efSGarrett D'Amore { NULL, NULL }, /* At */ 181*95c635efSGarrett D'Amore { NULL, NULL }, /* Bc */ 182*95c635efSGarrett D'Amore { termp_bf_pre, NULL }, /* Bf */ 183*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bo */ 184*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bq */ 185*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Bsx */ 186*95c635efSGarrett D'Amore { termp_bx_pre, NULL }, /* Bx */ 187*95c635efSGarrett D'Amore { NULL, NULL }, /* Db */ 188*95c635efSGarrett D'Amore { NULL, NULL }, /* Dc */ 189*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Do */ 190*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Dq */ 191*95c635efSGarrett D'Amore { NULL, NULL }, /* Ec */ /* FIXME: no space */ 192*95c635efSGarrett D'Amore { NULL, NULL }, /* Ef */ 193*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Em */ 194*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Eo */ 195*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Fx */ 196*95c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ms */ 197*95c635efSGarrett D'Amore { termp_igndelim_pre, NULL }, /* No */ 198*95c635efSGarrett D'Amore { termp_ns_pre, NULL }, /* Ns */ 199*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Nx */ 200*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ox */ 201*95c635efSGarrett D'Amore { NULL, NULL }, /* Pc */ 202*95c635efSGarrett D'Amore { termp_igndelim_pre, termp_pf_post }, /* Pf */ 203*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Po */ 204*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Pq */ 205*95c635efSGarrett D'Amore { NULL, NULL }, /* Qc */ 206*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ql */ 207*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qo */ 208*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qq */ 209*95c635efSGarrett D'Amore { NULL, NULL }, /* Re */ 210*95c635efSGarrett D'Amore { termp_rs_pre, NULL }, /* Rs */ 211*95c635efSGarrett D'Amore { NULL, NULL }, /* Sc */ 212*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* So */ 213*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Sq */ 214*95c635efSGarrett D'Amore { termp_sm_pre, NULL }, /* Sm */ 215*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Sx */ 216*95c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Sy */ 217*95c635efSGarrett D'Amore { NULL, NULL }, /* Tn */ 218*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ux */ 219*95c635efSGarrett D'Amore { NULL, NULL }, /* Xc */ 220*95c635efSGarrett D'Amore { NULL, NULL }, /* Xo */ 221*95c635efSGarrett D'Amore { termp_fo_pre, termp_fo_post }, /* Fo */ 222*95c635efSGarrett D'Amore { NULL, NULL }, /* Fc */ 223*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Oo */ 224*95c635efSGarrett D'Amore { NULL, NULL }, /* Oc */ 225*95c635efSGarrett D'Amore { termp_bk_pre, termp_bk_post }, /* Bk */ 226*95c635efSGarrett D'Amore { NULL, NULL }, /* Ek */ 227*95c635efSGarrett D'Amore { termp_bt_pre, NULL }, /* Bt */ 228*95c635efSGarrett D'Amore { NULL, NULL }, /* Hf */ 229*95c635efSGarrett D'Amore { NULL, NULL }, /* Fr */ 230*95c635efSGarrett D'Amore { termp_ud_pre, NULL }, /* Ud */ 231*95c635efSGarrett D'Amore { NULL, termp_lb_post }, /* Lb */ 232*95c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Lp */ 233*95c635efSGarrett D'Amore { termp_lk_pre, NULL }, /* Lk */ 234*95c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Mt */ 235*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Brq */ 236*95c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bro */ 237*95c635efSGarrett D'Amore { NULL, NULL }, /* Brc */ 238*95c635efSGarrett D'Amore { NULL, termp____post }, /* %C */ 239*95c635efSGarrett D'Amore { NULL, NULL }, /* Es */ /* TODO */ 240*95c635efSGarrett D'Amore { NULL, NULL }, /* En */ /* TODO */ 241*95c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Dx */ 242*95c635efSGarrett D'Amore { NULL, termp____post }, /* %Q */ 243*95c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* br */ 244*95c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* sp */ 245*95c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %U */ 246*95c635efSGarrett D'Amore { NULL, NULL }, /* Ta */ 247*95c635efSGarrett D'Amore }; 248*95c635efSGarrett D'Amore 249*95c635efSGarrett D'Amore 250*95c635efSGarrett D'Amore void 251*95c635efSGarrett D'Amore terminal_mdoc(void *arg, const struct mdoc *mdoc) 252*95c635efSGarrett D'Amore { 253*95c635efSGarrett D'Amore const struct mdoc_node *n; 254*95c635efSGarrett D'Amore const struct mdoc_meta *m; 255*95c635efSGarrett D'Amore struct termp *p; 256*95c635efSGarrett D'Amore 257*95c635efSGarrett D'Amore p = (struct termp *)arg; 258*95c635efSGarrett D'Amore 259*95c635efSGarrett D'Amore if (0 == p->defindent) 260*95c635efSGarrett D'Amore p->defindent = 5; 261*95c635efSGarrett D'Amore 262*95c635efSGarrett D'Amore p->overstep = 0; 263*95c635efSGarrett D'Amore p->maxrmargin = p->defrmargin; 264*95c635efSGarrett D'Amore p->tabwidth = term_len(p, 5); 265*95c635efSGarrett D'Amore 266*95c635efSGarrett D'Amore if (NULL == p->symtab) 267*95c635efSGarrett D'Amore p->symtab = mchars_alloc(); 268*95c635efSGarrett D'Amore 269*95c635efSGarrett D'Amore n = mdoc_node(mdoc); 270*95c635efSGarrett D'Amore m = mdoc_meta(mdoc); 271*95c635efSGarrett D'Amore 272*95c635efSGarrett D'Amore term_begin(p, print_mdoc_head, print_mdoc_foot, m); 273*95c635efSGarrett D'Amore 274*95c635efSGarrett D'Amore if (n->child) 275*95c635efSGarrett D'Amore print_mdoc_nodelist(p, NULL, m, n->child); 276*95c635efSGarrett D'Amore 277*95c635efSGarrett D'Amore term_end(p); 278*95c635efSGarrett D'Amore } 279*95c635efSGarrett D'Amore 280*95c635efSGarrett D'Amore 281*95c635efSGarrett D'Amore static void 282*95c635efSGarrett D'Amore print_mdoc_nodelist(DECL_ARGS) 283*95c635efSGarrett D'Amore { 284*95c635efSGarrett D'Amore 285*95c635efSGarrett D'Amore print_mdoc_node(p, pair, m, n); 286*95c635efSGarrett D'Amore if (n->next) 287*95c635efSGarrett D'Amore print_mdoc_nodelist(p, pair, m, n->next); 288*95c635efSGarrett D'Amore } 289*95c635efSGarrett D'Amore 290*95c635efSGarrett D'Amore 291*95c635efSGarrett D'Amore /* ARGSUSED */ 292*95c635efSGarrett D'Amore static void 293*95c635efSGarrett D'Amore print_mdoc_node(DECL_ARGS) 294*95c635efSGarrett D'Amore { 295*95c635efSGarrett D'Amore int chld; 296*95c635efSGarrett D'Amore const void *font; 297*95c635efSGarrett D'Amore struct termpair npair; 298*95c635efSGarrett D'Amore size_t offset, rmargin; 299*95c635efSGarrett D'Amore 300*95c635efSGarrett D'Amore chld = 1; 301*95c635efSGarrett D'Amore offset = p->offset; 302*95c635efSGarrett D'Amore rmargin = p->rmargin; 303*95c635efSGarrett D'Amore font = term_fontq(p); 304*95c635efSGarrett D'Amore 305*95c635efSGarrett D'Amore memset(&npair, 0, sizeof(struct termpair)); 306*95c635efSGarrett D'Amore npair.ppair = pair; 307*95c635efSGarrett D'Amore 308*95c635efSGarrett D'Amore /* 309*95c635efSGarrett D'Amore * Keeps only work until the end of a line. If a keep was 310*95c635efSGarrett D'Amore * invoked in a prior line, revert it to PREKEEP. 311*95c635efSGarrett D'Amore * 312*95c635efSGarrett D'Amore * Also let SYNPRETTY sections behave as if they were wrapped 313*95c635efSGarrett D'Amore * in a `Bk' block. 314*95c635efSGarrett D'Amore */ 315*95c635efSGarrett D'Amore 316*95c635efSGarrett D'Amore if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) { 317*95c635efSGarrett D'Amore if (n->prev && n->prev->line != n->line) { 318*95c635efSGarrett D'Amore p->flags &= ~TERMP_KEEP; 319*95c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP; 320*95c635efSGarrett D'Amore } else if (NULL == n->prev) { 321*95c635efSGarrett D'Amore if (n->parent && n->parent->line != n->line) { 322*95c635efSGarrett D'Amore p->flags &= ~TERMP_KEEP; 323*95c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP; 324*95c635efSGarrett D'Amore } 325*95c635efSGarrett D'Amore } 326*95c635efSGarrett D'Amore } 327*95c635efSGarrett D'Amore 328*95c635efSGarrett D'Amore /* 329*95c635efSGarrett D'Amore * Since SYNPRETTY sections aren't "turned off" with `Ek', 330*95c635efSGarrett D'Amore * we have to intuit whether we should disable formatting. 331*95c635efSGarrett D'Amore */ 332*95c635efSGarrett D'Amore 333*95c635efSGarrett D'Amore if ( ! (MDOC_SYNPRETTY & n->flags) && 334*95c635efSGarrett D'Amore ((n->prev && MDOC_SYNPRETTY & n->prev->flags) || 335*95c635efSGarrett D'Amore (n->parent && MDOC_SYNPRETTY & n->parent->flags))) 336*95c635efSGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); 337*95c635efSGarrett D'Amore 338*95c635efSGarrett D'Amore /* 339*95c635efSGarrett D'Amore * After the keep flags have been set up, we may now 340*95c635efSGarrett D'Amore * produce output. Note that some pre-handlers do so. 341*95c635efSGarrett D'Amore */ 342*95c635efSGarrett D'Amore 343*95c635efSGarrett D'Amore switch (n->type) { 344*95c635efSGarrett D'Amore case (MDOC_TEXT): 345*95c635efSGarrett D'Amore if (' ' == *n->string && MDOC_LINE & n->flags) 346*95c635efSGarrett D'Amore term_newln(p); 347*95c635efSGarrett D'Amore if (MDOC_DELIMC & n->flags) 348*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 349*95c635efSGarrett D'Amore term_word(p, n->string); 350*95c635efSGarrett D'Amore if (MDOC_DELIMO & n->flags) 351*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 352*95c635efSGarrett D'Amore break; 353*95c635efSGarrett D'Amore case (MDOC_EQN): 354*95c635efSGarrett D'Amore term_eqn(p, n->eqn); 355*95c635efSGarrett D'Amore break; 356*95c635efSGarrett D'Amore case (MDOC_TBL): 357*95c635efSGarrett D'Amore term_tbl(p, n->span); 358*95c635efSGarrett D'Amore break; 359*95c635efSGarrett D'Amore default: 360*95c635efSGarrett D'Amore if (termacts[n->tok].pre && ENDBODY_NOT == n->end) 361*95c635efSGarrett D'Amore chld = (*termacts[n->tok].pre) 362*95c635efSGarrett D'Amore (p, &npair, m, n); 363*95c635efSGarrett D'Amore break; 364*95c635efSGarrett D'Amore } 365*95c635efSGarrett D'Amore 366*95c635efSGarrett D'Amore if (chld && n->child) 367*95c635efSGarrett D'Amore print_mdoc_nodelist(p, &npair, m, n->child); 368*95c635efSGarrett D'Amore 369*95c635efSGarrett D'Amore term_fontpopq(p, font); 370*95c635efSGarrett D'Amore 371*95c635efSGarrett D'Amore switch (n->type) { 372*95c635efSGarrett D'Amore case (MDOC_TEXT): 373*95c635efSGarrett D'Amore break; 374*95c635efSGarrett D'Amore case (MDOC_TBL): 375*95c635efSGarrett D'Amore break; 376*95c635efSGarrett D'Amore case (MDOC_EQN): 377*95c635efSGarrett D'Amore break; 378*95c635efSGarrett D'Amore default: 379*95c635efSGarrett D'Amore if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) 380*95c635efSGarrett D'Amore break; 381*95c635efSGarrett D'Amore (void)(*termacts[n->tok].post)(p, &npair, m, n); 382*95c635efSGarrett D'Amore 383*95c635efSGarrett D'Amore /* 384*95c635efSGarrett D'Amore * Explicit end tokens not only call the post 385*95c635efSGarrett D'Amore * handler, but also tell the respective block 386*95c635efSGarrett D'Amore * that it must not call the post handler again. 387*95c635efSGarrett D'Amore */ 388*95c635efSGarrett D'Amore if (ENDBODY_NOT != n->end) 389*95c635efSGarrett D'Amore n->pending->flags |= MDOC_ENDED; 390*95c635efSGarrett D'Amore 391*95c635efSGarrett D'Amore /* 392*95c635efSGarrett D'Amore * End of line terminating an implicit block 393*95c635efSGarrett D'Amore * while an explicit block is still open. 394*95c635efSGarrett D'Amore * Continue the explicit block without spacing. 395*95c635efSGarrett D'Amore */ 396*95c635efSGarrett D'Amore if (ENDBODY_NOSPACE == n->end) 397*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 398*95c635efSGarrett D'Amore break; 399*95c635efSGarrett D'Amore } 400*95c635efSGarrett D'Amore 401*95c635efSGarrett D'Amore if (MDOC_EOS & n->flags) 402*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 403*95c635efSGarrett D'Amore 404*95c635efSGarrett D'Amore p->offset = offset; 405*95c635efSGarrett D'Amore p->rmargin = rmargin; 406*95c635efSGarrett D'Amore } 407*95c635efSGarrett D'Amore 408*95c635efSGarrett D'Amore 409*95c635efSGarrett D'Amore static void 410*95c635efSGarrett D'Amore print_mdoc_foot(struct termp *p, const void *arg) 411*95c635efSGarrett D'Amore { 412*95c635efSGarrett D'Amore const struct mdoc_meta *m; 413*95c635efSGarrett D'Amore 414*95c635efSGarrett D'Amore m = (const struct mdoc_meta *)arg; 415*95c635efSGarrett D'Amore 416*95c635efSGarrett D'Amore term_fontrepl(p, TERMFONT_NONE); 417*95c635efSGarrett D'Amore 418*95c635efSGarrett D'Amore /* 419*95c635efSGarrett D'Amore * Output the footer in new-groff style, that is, three columns 420*95c635efSGarrett D'Amore * with the middle being the manual date and flanking columns 421*95c635efSGarrett D'Amore * being the operating system: 422*95c635efSGarrett D'Amore * 423*95c635efSGarrett D'Amore * SYSTEM DATE SYSTEM 424*95c635efSGarrett D'Amore */ 425*95c635efSGarrett D'Amore 426*95c635efSGarrett D'Amore term_vspace(p); 427*95c635efSGarrett D'Amore 428*95c635efSGarrett D'Amore p->offset = 0; 429*95c635efSGarrett D'Amore p->rmargin = (p->maxrmargin - 430*95c635efSGarrett D'Amore term_strlen(p, m->date) + term_len(p, 1)) / 2; 431*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; 432*95c635efSGarrett D'Amore 433*95c635efSGarrett D'Amore term_word(p, m->os); 434*95c635efSGarrett D'Amore term_flushln(p); 435*95c635efSGarrett D'Amore 436*95c635efSGarrett D'Amore p->offset = p->rmargin; 437*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin - term_strlen(p, m->os); 438*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 439*95c635efSGarrett D'Amore 440*95c635efSGarrett D'Amore term_word(p, m->date); 441*95c635efSGarrett D'Amore term_flushln(p); 442*95c635efSGarrett D'Amore 443*95c635efSGarrett D'Amore p->offset = p->rmargin; 444*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 445*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 446*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 447*95c635efSGarrett D'Amore 448*95c635efSGarrett D'Amore term_word(p, m->os); 449*95c635efSGarrett D'Amore term_flushln(p); 450*95c635efSGarrett D'Amore 451*95c635efSGarrett D'Amore p->offset = 0; 452*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 453*95c635efSGarrett D'Amore p->flags = 0; 454*95c635efSGarrett D'Amore } 455*95c635efSGarrett D'Amore 456*95c635efSGarrett D'Amore 457*95c635efSGarrett D'Amore static void 458*95c635efSGarrett D'Amore print_mdoc_head(struct termp *p, const void *arg) 459*95c635efSGarrett D'Amore { 460*95c635efSGarrett D'Amore char buf[BUFSIZ], title[BUFSIZ]; 461*95c635efSGarrett D'Amore size_t buflen, titlen; 462*95c635efSGarrett D'Amore const struct mdoc_meta *m; 463*95c635efSGarrett D'Amore 464*95c635efSGarrett D'Amore m = (const struct mdoc_meta *)arg; 465*95c635efSGarrett D'Amore 466*95c635efSGarrett D'Amore /* 467*95c635efSGarrett D'Amore * The header is strange. It has three components, which are 468*95c635efSGarrett D'Amore * really two with the first duplicated. It goes like this: 469*95c635efSGarrett D'Amore * 470*95c635efSGarrett D'Amore * IDENTIFIER TITLE IDENTIFIER 471*95c635efSGarrett D'Amore * 472*95c635efSGarrett D'Amore * The IDENTIFIER is NAME(SECTION), which is the command-name 473*95c635efSGarrett D'Amore * (if given, or "unknown" if not) followed by the manual page 474*95c635efSGarrett D'Amore * section. These are given in `Dt'. The TITLE is a free-form 475*95c635efSGarrett D'Amore * string depending on the manual volume. If not specified, it 476*95c635efSGarrett D'Amore * switches on the manual section. 477*95c635efSGarrett D'Amore */ 478*95c635efSGarrett D'Amore 479*95c635efSGarrett D'Amore p->offset = 0; 480*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 481*95c635efSGarrett D'Amore 482*95c635efSGarrett D'Amore assert(m->vol); 483*95c635efSGarrett D'Amore strlcpy(buf, m->vol, BUFSIZ); 484*95c635efSGarrett D'Amore buflen = term_strlen(p, buf); 485*95c635efSGarrett D'Amore 486*95c635efSGarrett D'Amore if (m->arch) { 487*95c635efSGarrett D'Amore strlcat(buf, " (", BUFSIZ); 488*95c635efSGarrett D'Amore strlcat(buf, m->arch, BUFSIZ); 489*95c635efSGarrett D'Amore strlcat(buf, ")", BUFSIZ); 490*95c635efSGarrett D'Amore } 491*95c635efSGarrett D'Amore 492*95c635efSGarrett D'Amore snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec); 493*95c635efSGarrett D'Amore titlen = term_strlen(p, title); 494*95c635efSGarrett D'Amore 495*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; 496*95c635efSGarrett D'Amore p->offset = 0; 497*95c635efSGarrett D'Amore p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ? 498*95c635efSGarrett D'Amore (p->maxrmargin - 499*95c635efSGarrett D'Amore term_strlen(p, buf) + term_len(p, 1)) / 2 : 500*95c635efSGarrett D'Amore p->maxrmargin - buflen; 501*95c635efSGarrett D'Amore 502*95c635efSGarrett D'Amore term_word(p, title); 503*95c635efSGarrett D'Amore term_flushln(p); 504*95c635efSGarrett D'Amore 505*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 506*95c635efSGarrett D'Amore p->offset = p->rmargin; 507*95c635efSGarrett D'Amore p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? 508*95c635efSGarrett D'Amore p->maxrmargin - titlen : p->maxrmargin; 509*95c635efSGarrett D'Amore 510*95c635efSGarrett D'Amore term_word(p, buf); 511*95c635efSGarrett D'Amore term_flushln(p); 512*95c635efSGarrett D'Amore 513*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 514*95c635efSGarrett D'Amore if (p->rmargin + titlen <= p->maxrmargin) { 515*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 516*95c635efSGarrett D'Amore p->offset = p->rmargin; 517*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 518*95c635efSGarrett D'Amore term_word(p, title); 519*95c635efSGarrett D'Amore term_flushln(p); 520*95c635efSGarrett D'Amore } 521*95c635efSGarrett D'Amore 522*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE; 523*95c635efSGarrett D'Amore p->offset = 0; 524*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 525*95c635efSGarrett D'Amore } 526*95c635efSGarrett D'Amore 527*95c635efSGarrett D'Amore 528*95c635efSGarrett D'Amore static size_t 529*95c635efSGarrett D'Amore a2height(const struct termp *p, const char *v) 530*95c635efSGarrett D'Amore { 531*95c635efSGarrett D'Amore struct roffsu su; 532*95c635efSGarrett D'Amore 533*95c635efSGarrett D'Amore 534*95c635efSGarrett D'Amore assert(v); 535*95c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_VS)) 536*95c635efSGarrett D'Amore SCALE_VS_INIT(&su, atoi(v)); 537*95c635efSGarrett D'Amore 538*95c635efSGarrett D'Amore return(term_vspan(p, &su)); 539*95c635efSGarrett D'Amore } 540*95c635efSGarrett D'Amore 541*95c635efSGarrett D'Amore 542*95c635efSGarrett D'Amore static size_t 543*95c635efSGarrett D'Amore a2width(const struct termp *p, const char *v) 544*95c635efSGarrett D'Amore { 545*95c635efSGarrett D'Amore struct roffsu su; 546*95c635efSGarrett D'Amore 547*95c635efSGarrett D'Amore assert(v); 548*95c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_MAX)) 549*95c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v)); 550*95c635efSGarrett D'Amore 551*95c635efSGarrett D'Amore return(term_hspan(p, &su)); 552*95c635efSGarrett D'Amore } 553*95c635efSGarrett D'Amore 554*95c635efSGarrett D'Amore 555*95c635efSGarrett D'Amore static size_t 556*95c635efSGarrett D'Amore a2offs(const struct termp *p, const char *v) 557*95c635efSGarrett D'Amore { 558*95c635efSGarrett D'Amore struct roffsu su; 559*95c635efSGarrett D'Amore 560*95c635efSGarrett D'Amore if ('\0' == *v) 561*95c635efSGarrett D'Amore return(0); 562*95c635efSGarrett D'Amore else if (0 == strcmp(v, "left")) 563*95c635efSGarrett D'Amore return(0); 564*95c635efSGarrett D'Amore else if (0 == strcmp(v, "indent")) 565*95c635efSGarrett D'Amore return(term_len(p, p->defindent + 1)); 566*95c635efSGarrett D'Amore else if (0 == strcmp(v, "indent-two")) 567*95c635efSGarrett D'Amore return(term_len(p, (p->defindent + 1) * 2)); 568*95c635efSGarrett D'Amore else if ( ! a2roffsu(v, &su, SCALE_MAX)) 569*95c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v)); 570*95c635efSGarrett D'Amore 571*95c635efSGarrett D'Amore return(term_hspan(p, &su)); 572*95c635efSGarrett D'Amore } 573*95c635efSGarrett D'Amore 574*95c635efSGarrett D'Amore 575*95c635efSGarrett D'Amore /* 576*95c635efSGarrett D'Amore * Determine how much space to print out before block elements of `It' 577*95c635efSGarrett D'Amore * (and thus `Bl') and `Bd'. And then go ahead and print that space, 578*95c635efSGarrett D'Amore * too. 579*95c635efSGarrett D'Amore */ 580*95c635efSGarrett D'Amore static void 581*95c635efSGarrett D'Amore print_bvspace(struct termp *p, 582*95c635efSGarrett D'Amore const struct mdoc_node *bl, 583*95c635efSGarrett D'Amore const struct mdoc_node *n) 584*95c635efSGarrett D'Amore { 585*95c635efSGarrett D'Amore const struct mdoc_node *nn; 586*95c635efSGarrett D'Amore 587*95c635efSGarrett D'Amore assert(n); 588*95c635efSGarrett D'Amore 589*95c635efSGarrett D'Amore term_newln(p); 590*95c635efSGarrett D'Amore 591*95c635efSGarrett D'Amore if (MDOC_Bd == bl->tok && bl->norm->Bd.comp) 592*95c635efSGarrett D'Amore return; 593*95c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && bl->norm->Bl.comp) 594*95c635efSGarrett D'Amore return; 595*95c635efSGarrett D'Amore 596*95c635efSGarrett D'Amore /* Do not vspace directly after Ss/Sh. */ 597*95c635efSGarrett D'Amore 598*95c635efSGarrett D'Amore for (nn = n; nn; nn = nn->parent) { 599*95c635efSGarrett D'Amore if (MDOC_BLOCK != nn->type) 600*95c635efSGarrett D'Amore continue; 601*95c635efSGarrett D'Amore if (MDOC_Ss == nn->tok) 602*95c635efSGarrett D'Amore return; 603*95c635efSGarrett D'Amore if (MDOC_Sh == nn->tok) 604*95c635efSGarrett D'Amore return; 605*95c635efSGarrett D'Amore if (NULL == nn->prev) 606*95c635efSGarrett D'Amore continue; 607*95c635efSGarrett D'Amore break; 608*95c635efSGarrett D'Amore } 609*95c635efSGarrett D'Amore 610*95c635efSGarrett D'Amore /* A `-column' does not assert vspace within the list. */ 611*95c635efSGarrett D'Amore 612*95c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type) 613*95c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok) 614*95c635efSGarrett D'Amore return; 615*95c635efSGarrett D'Amore 616*95c635efSGarrett D'Amore /* A `-diag' without body does not vspace. */ 617*95c635efSGarrett D'Amore 618*95c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type) 619*95c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok) { 620*95c635efSGarrett D'Amore assert(n->prev->body); 621*95c635efSGarrett D'Amore if (NULL == n->prev->body->child) 622*95c635efSGarrett D'Amore return; 623*95c635efSGarrett D'Amore } 624*95c635efSGarrett D'Amore 625*95c635efSGarrett D'Amore term_vspace(p); 626*95c635efSGarrett D'Amore } 627*95c635efSGarrett D'Amore 628*95c635efSGarrett D'Amore 629*95c635efSGarrett D'Amore /* ARGSUSED */ 630*95c635efSGarrett D'Amore static int 631*95c635efSGarrett D'Amore termp_it_pre(DECL_ARGS) 632*95c635efSGarrett D'Amore { 633*95c635efSGarrett D'Amore const struct mdoc_node *bl, *nn; 634*95c635efSGarrett D'Amore char buf[7]; 635*95c635efSGarrett D'Amore int i; 636*95c635efSGarrett D'Amore size_t width, offset, ncols, dcol; 637*95c635efSGarrett D'Amore enum mdoc_list type; 638*95c635efSGarrett D'Amore 639*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 640*95c635efSGarrett D'Amore print_bvspace(p, n->parent->parent, n); 641*95c635efSGarrett D'Amore return(1); 642*95c635efSGarrett D'Amore } 643*95c635efSGarrett D'Amore 644*95c635efSGarrett D'Amore bl = n->parent->parent->parent; 645*95c635efSGarrett D'Amore type = bl->norm->Bl.type; 646*95c635efSGarrett D'Amore 647*95c635efSGarrett D'Amore /* 648*95c635efSGarrett D'Amore * First calculate width and offset. This is pretty easy unless 649*95c635efSGarrett D'Amore * we're a -column list, in which case all prior columns must 650*95c635efSGarrett D'Amore * be accounted for. 651*95c635efSGarrett D'Amore */ 652*95c635efSGarrett D'Amore 653*95c635efSGarrett D'Amore width = offset = 0; 654*95c635efSGarrett D'Amore 655*95c635efSGarrett D'Amore if (bl->norm->Bl.offs) 656*95c635efSGarrett D'Amore offset = a2offs(p, bl->norm->Bl.offs); 657*95c635efSGarrett D'Amore 658*95c635efSGarrett D'Amore switch (type) { 659*95c635efSGarrett D'Amore case (LIST_column): 660*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 661*95c635efSGarrett D'Amore break; 662*95c635efSGarrett D'Amore 663*95c635efSGarrett D'Amore /* 664*95c635efSGarrett D'Amore * Imitate groff's column handling: 665*95c635efSGarrett D'Amore * - For each earlier column, add its width. 666*95c635efSGarrett D'Amore * - For less than 5 columns, add four more blanks per 667*95c635efSGarrett D'Amore * column. 668*95c635efSGarrett D'Amore * - For exactly 5 columns, add three more blank per 669*95c635efSGarrett D'Amore * column. 670*95c635efSGarrett D'Amore * - For more than 5 columns, add only one column. 671*95c635efSGarrett D'Amore */ 672*95c635efSGarrett D'Amore ncols = bl->norm->Bl.ncols; 673*95c635efSGarrett D'Amore 674*95c635efSGarrett D'Amore /* LINTED */ 675*95c635efSGarrett D'Amore dcol = ncols < 5 ? term_len(p, 4) : 676*95c635efSGarrett D'Amore ncols == 5 ? term_len(p, 3) : term_len(p, 1); 677*95c635efSGarrett D'Amore 678*95c635efSGarrett D'Amore /* 679*95c635efSGarrett D'Amore * Calculate the offset by applying all prior MDOC_BODY, 680*95c635efSGarrett D'Amore * so we stop at the MDOC_HEAD (NULL == nn->prev). 681*95c635efSGarrett D'Amore */ 682*95c635efSGarrett D'Amore 683*95c635efSGarrett D'Amore for (i = 0, nn = n->prev; 684*95c635efSGarrett D'Amore nn->prev && i < (int)ncols; 685*95c635efSGarrett D'Amore nn = nn->prev, i++) 686*95c635efSGarrett D'Amore offset += dcol + a2width 687*95c635efSGarrett D'Amore (p, bl->norm->Bl.cols[i]); 688*95c635efSGarrett D'Amore 689*95c635efSGarrett D'Amore /* 690*95c635efSGarrett D'Amore * When exceeding the declared number of columns, leave 691*95c635efSGarrett D'Amore * the remaining widths at 0. This will later be 692*95c635efSGarrett D'Amore * adjusted to the default width of 10, or, for the last 693*95c635efSGarrett D'Amore * column, stretched to the right margin. 694*95c635efSGarrett D'Amore */ 695*95c635efSGarrett D'Amore if (i >= (int)ncols) 696*95c635efSGarrett D'Amore break; 697*95c635efSGarrett D'Amore 698*95c635efSGarrett D'Amore /* 699*95c635efSGarrett D'Amore * Use the declared column widths, extended as explained 700*95c635efSGarrett D'Amore * in the preceding paragraph. 701*95c635efSGarrett D'Amore */ 702*95c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.cols[i]) + dcol; 703*95c635efSGarrett D'Amore break; 704*95c635efSGarrett D'Amore default: 705*95c635efSGarrett D'Amore if (NULL == bl->norm->Bl.width) 706*95c635efSGarrett D'Amore break; 707*95c635efSGarrett D'Amore 708*95c635efSGarrett D'Amore /* 709*95c635efSGarrett D'Amore * Note: buffer the width by 2, which is groff's magic 710*95c635efSGarrett D'Amore * number for buffering single arguments. See the above 711*95c635efSGarrett D'Amore * handling for column for how this changes. 712*95c635efSGarrett D'Amore */ 713*95c635efSGarrett D'Amore assert(bl->norm->Bl.width); 714*95c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.width) + term_len(p, 2); 715*95c635efSGarrett D'Amore break; 716*95c635efSGarrett D'Amore } 717*95c635efSGarrett D'Amore 718*95c635efSGarrett D'Amore /* 719*95c635efSGarrett D'Amore * List-type can override the width in the case of fixed-head 720*95c635efSGarrett D'Amore * values (bullet, dash/hyphen, enum). Tags need a non-zero 721*95c635efSGarrett D'Amore * offset. 722*95c635efSGarrett D'Amore */ 723*95c635efSGarrett D'Amore 724*95c635efSGarrett D'Amore switch (type) { 725*95c635efSGarrett D'Amore case (LIST_bullet): 726*95c635efSGarrett D'Amore /* FALLTHROUGH */ 727*95c635efSGarrett D'Amore case (LIST_dash): 728*95c635efSGarrett D'Amore /* FALLTHROUGH */ 729*95c635efSGarrett D'Amore case (LIST_hyphen): 730*95c635efSGarrett D'Amore if (width < term_len(p, 4)) 731*95c635efSGarrett D'Amore width = term_len(p, 4); 732*95c635efSGarrett D'Amore break; 733*95c635efSGarrett D'Amore case (LIST_enum): 734*95c635efSGarrett D'Amore if (width < term_len(p, 5)) 735*95c635efSGarrett D'Amore width = term_len(p, 5); 736*95c635efSGarrett D'Amore break; 737*95c635efSGarrett D'Amore case (LIST_hang): 738*95c635efSGarrett D'Amore if (0 == width) 739*95c635efSGarrett D'Amore width = term_len(p, 8); 740*95c635efSGarrett D'Amore break; 741*95c635efSGarrett D'Amore case (LIST_column): 742*95c635efSGarrett D'Amore /* FALLTHROUGH */ 743*95c635efSGarrett D'Amore case (LIST_tag): 744*95c635efSGarrett D'Amore if (0 == width) 745*95c635efSGarrett D'Amore width = term_len(p, 10); 746*95c635efSGarrett D'Amore break; 747*95c635efSGarrett D'Amore default: 748*95c635efSGarrett D'Amore break; 749*95c635efSGarrett D'Amore } 750*95c635efSGarrett D'Amore 751*95c635efSGarrett D'Amore /* 752*95c635efSGarrett D'Amore * Whitespace control. Inset bodies need an initial space, 753*95c635efSGarrett D'Amore * while diagonal bodies need two. 754*95c635efSGarrett D'Amore */ 755*95c635efSGarrett D'Amore 756*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 757*95c635efSGarrett D'Amore 758*95c635efSGarrett D'Amore switch (type) { 759*95c635efSGarrett D'Amore case (LIST_diag): 760*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) 761*95c635efSGarrett D'Amore term_word(p, "\\ \\ "); 762*95c635efSGarrett D'Amore break; 763*95c635efSGarrett D'Amore case (LIST_inset): 764*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) 765*95c635efSGarrett D'Amore term_word(p, "\\ "); 766*95c635efSGarrett D'Amore break; 767*95c635efSGarrett D'Amore default: 768*95c635efSGarrett D'Amore break; 769*95c635efSGarrett D'Amore } 770*95c635efSGarrett D'Amore 771*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 772*95c635efSGarrett D'Amore 773*95c635efSGarrett D'Amore switch (type) { 774*95c635efSGarrett D'Amore case (LIST_diag): 775*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 776*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 777*95c635efSGarrett D'Amore break; 778*95c635efSGarrett D'Amore default: 779*95c635efSGarrett D'Amore break; 780*95c635efSGarrett D'Amore } 781*95c635efSGarrett D'Amore 782*95c635efSGarrett D'Amore /* 783*95c635efSGarrett D'Amore * Pad and break control. This is the tricky part. These flags 784*95c635efSGarrett D'Amore * are documented in term_flushln() in term.c. Note that we're 785*95c635efSGarrett D'Amore * going to unset all of these flags in termp_it_post() when we 786*95c635efSGarrett D'Amore * exit. 787*95c635efSGarrett D'Amore */ 788*95c635efSGarrett D'Amore 789*95c635efSGarrett D'Amore switch (type) { 790*95c635efSGarrett D'Amore case (LIST_bullet): 791*95c635efSGarrett D'Amore /* FALLTHROUGH */ 792*95c635efSGarrett D'Amore case (LIST_dash): 793*95c635efSGarrett D'Amore /* FALLTHROUGH */ 794*95c635efSGarrett D'Amore case (LIST_enum): 795*95c635efSGarrett D'Amore /* FALLTHROUGH */ 796*95c635efSGarrett D'Amore case (LIST_hyphen): 797*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 798*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 799*95c635efSGarrett D'Amore break; 800*95c635efSGarrett D'Amore case (LIST_hang): 801*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 802*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 803*95c635efSGarrett D'Amore else 804*95c635efSGarrett D'Amore break; 805*95c635efSGarrett D'Amore 806*95c635efSGarrett D'Amore /* 807*95c635efSGarrett D'Amore * This is ugly. If `-hang' is specified and the body 808*95c635efSGarrett D'Amore * is a `Bl' or `Bd', then we want basically to nullify 809*95c635efSGarrett D'Amore * the "overstep" effect in term_flushln() and treat 810*95c635efSGarrett D'Amore * this as a `-ohang' list instead. 811*95c635efSGarrett D'Amore */ 812*95c635efSGarrett D'Amore if (n->next->child && 813*95c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok || 814*95c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok)) 815*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 816*95c635efSGarrett D'Amore else 817*95c635efSGarrett D'Amore p->flags |= TERMP_HANG; 818*95c635efSGarrett D'Amore break; 819*95c635efSGarrett D'Amore case (LIST_tag): 820*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 821*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE; 822*95c635efSGarrett D'Amore 823*95c635efSGarrett D'Amore if (MDOC_HEAD != n->type) 824*95c635efSGarrett D'Amore break; 825*95c635efSGarrett D'Amore if (NULL == n->next || NULL == n->next->child) 826*95c635efSGarrett D'Amore p->flags |= TERMP_DANGLE; 827*95c635efSGarrett D'Amore break; 828*95c635efSGarrett D'Amore case (LIST_column): 829*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 830*95c635efSGarrett D'Amore break; 831*95c635efSGarrett D'Amore 832*95c635efSGarrett D'Amore if (NULL == n->next) 833*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 834*95c635efSGarrett D'Amore else 835*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 836*95c635efSGarrett D'Amore 837*95c635efSGarrett D'Amore break; 838*95c635efSGarrett D'Amore case (LIST_diag): 839*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 840*95c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 841*95c635efSGarrett D'Amore break; 842*95c635efSGarrett D'Amore default: 843*95c635efSGarrett D'Amore break; 844*95c635efSGarrett D'Amore } 845*95c635efSGarrett D'Amore 846*95c635efSGarrett D'Amore /* 847*95c635efSGarrett D'Amore * Margin control. Set-head-width lists have their right 848*95c635efSGarrett D'Amore * margins shortened. The body for these lists has the offset 849*95c635efSGarrett D'Amore * necessarily lengthened. Everybody gets the offset. 850*95c635efSGarrett D'Amore */ 851*95c635efSGarrett D'Amore 852*95c635efSGarrett D'Amore p->offset += offset; 853*95c635efSGarrett D'Amore 854*95c635efSGarrett D'Amore switch (type) { 855*95c635efSGarrett D'Amore case (LIST_hang): 856*95c635efSGarrett D'Amore /* 857*95c635efSGarrett D'Amore * Same stipulation as above, regarding `-hang'. We 858*95c635efSGarrett D'Amore * don't want to recalculate rmargin and offsets when 859*95c635efSGarrett D'Amore * using `Bd' or `Bl' within `-hang' overstep lists. 860*95c635efSGarrett D'Amore */ 861*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child && 862*95c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok || 863*95c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok)) 864*95c635efSGarrett D'Amore break; 865*95c635efSGarrett D'Amore /* FALLTHROUGH */ 866*95c635efSGarrett D'Amore case (LIST_bullet): 867*95c635efSGarrett D'Amore /* FALLTHROUGH */ 868*95c635efSGarrett D'Amore case (LIST_dash): 869*95c635efSGarrett D'Amore /* FALLTHROUGH */ 870*95c635efSGarrett D'Amore case (LIST_enum): 871*95c635efSGarrett D'Amore /* FALLTHROUGH */ 872*95c635efSGarrett D'Amore case (LIST_hyphen): 873*95c635efSGarrett D'Amore /* FALLTHROUGH */ 874*95c635efSGarrett D'Amore case (LIST_tag): 875*95c635efSGarrett D'Amore assert(width); 876*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 877*95c635efSGarrett D'Amore p->rmargin = p->offset + width; 878*95c635efSGarrett D'Amore else 879*95c635efSGarrett D'Amore p->offset += width; 880*95c635efSGarrett D'Amore break; 881*95c635efSGarrett D'Amore case (LIST_column): 882*95c635efSGarrett D'Amore assert(width); 883*95c635efSGarrett D'Amore p->rmargin = p->offset + width; 884*95c635efSGarrett D'Amore /* 885*95c635efSGarrett D'Amore * XXX - this behaviour is not documented: the 886*95c635efSGarrett D'Amore * right-most column is filled to the right margin. 887*95c635efSGarrett D'Amore */ 888*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 889*95c635efSGarrett D'Amore break; 890*95c635efSGarrett D'Amore if (NULL == n->next && p->rmargin < p->maxrmargin) 891*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 892*95c635efSGarrett D'Amore break; 893*95c635efSGarrett D'Amore default: 894*95c635efSGarrett D'Amore break; 895*95c635efSGarrett D'Amore } 896*95c635efSGarrett D'Amore 897*95c635efSGarrett D'Amore /* 898*95c635efSGarrett D'Amore * The dash, hyphen, bullet and enum lists all have a special 899*95c635efSGarrett D'Amore * HEAD character (temporarily bold, in some cases). 900*95c635efSGarrett D'Amore */ 901*95c635efSGarrett D'Amore 902*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 903*95c635efSGarrett D'Amore switch (type) { 904*95c635efSGarrett D'Amore case (LIST_bullet): 905*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 906*95c635efSGarrett D'Amore term_word(p, "\\[bu]"); 907*95c635efSGarrett D'Amore term_fontpop(p); 908*95c635efSGarrett D'Amore break; 909*95c635efSGarrett D'Amore case (LIST_dash): 910*95c635efSGarrett D'Amore /* FALLTHROUGH */ 911*95c635efSGarrett D'Amore case (LIST_hyphen): 912*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 913*95c635efSGarrett D'Amore term_word(p, "\\(hy"); 914*95c635efSGarrett D'Amore term_fontpop(p); 915*95c635efSGarrett D'Amore break; 916*95c635efSGarrett D'Amore case (LIST_enum): 917*95c635efSGarrett D'Amore (pair->ppair->ppair->count)++; 918*95c635efSGarrett D'Amore snprintf(buf, sizeof(buf), "%d.", 919*95c635efSGarrett D'Amore pair->ppair->ppair->count); 920*95c635efSGarrett D'Amore term_word(p, buf); 921*95c635efSGarrett D'Amore break; 922*95c635efSGarrett D'Amore default: 923*95c635efSGarrett D'Amore break; 924*95c635efSGarrett D'Amore } 925*95c635efSGarrett D'Amore 926*95c635efSGarrett D'Amore /* 927*95c635efSGarrett D'Amore * If we're not going to process our children, indicate so here. 928*95c635efSGarrett D'Amore */ 929*95c635efSGarrett D'Amore 930*95c635efSGarrett D'Amore switch (type) { 931*95c635efSGarrett D'Amore case (LIST_bullet): 932*95c635efSGarrett D'Amore /* FALLTHROUGH */ 933*95c635efSGarrett D'Amore case (LIST_item): 934*95c635efSGarrett D'Amore /* FALLTHROUGH */ 935*95c635efSGarrett D'Amore case (LIST_dash): 936*95c635efSGarrett D'Amore /* FALLTHROUGH */ 937*95c635efSGarrett D'Amore case (LIST_hyphen): 938*95c635efSGarrett D'Amore /* FALLTHROUGH */ 939*95c635efSGarrett D'Amore case (LIST_enum): 940*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 941*95c635efSGarrett D'Amore return(0); 942*95c635efSGarrett D'Amore break; 943*95c635efSGarrett D'Amore case (LIST_column): 944*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 945*95c635efSGarrett D'Amore return(0); 946*95c635efSGarrett D'Amore break; 947*95c635efSGarrett D'Amore default: 948*95c635efSGarrett D'Amore break; 949*95c635efSGarrett D'Amore } 950*95c635efSGarrett D'Amore 951*95c635efSGarrett D'Amore return(1); 952*95c635efSGarrett D'Amore } 953*95c635efSGarrett D'Amore 954*95c635efSGarrett D'Amore 955*95c635efSGarrett D'Amore /* ARGSUSED */ 956*95c635efSGarrett D'Amore static void 957*95c635efSGarrett D'Amore termp_it_post(DECL_ARGS) 958*95c635efSGarrett D'Amore { 959*95c635efSGarrett D'Amore enum mdoc_list type; 960*95c635efSGarrett D'Amore 961*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) 962*95c635efSGarrett D'Amore return; 963*95c635efSGarrett D'Amore 964*95c635efSGarrett D'Amore type = n->parent->parent->parent->norm->Bl.type; 965*95c635efSGarrett D'Amore 966*95c635efSGarrett D'Amore switch (type) { 967*95c635efSGarrett D'Amore case (LIST_item): 968*95c635efSGarrett D'Amore /* FALLTHROUGH */ 969*95c635efSGarrett D'Amore case (LIST_diag): 970*95c635efSGarrett D'Amore /* FALLTHROUGH */ 971*95c635efSGarrett D'Amore case (LIST_inset): 972*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) 973*95c635efSGarrett D'Amore term_newln(p); 974*95c635efSGarrett D'Amore break; 975*95c635efSGarrett D'Amore case (LIST_column): 976*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) 977*95c635efSGarrett D'Amore term_flushln(p); 978*95c635efSGarrett D'Amore break; 979*95c635efSGarrett D'Amore default: 980*95c635efSGarrett D'Amore term_newln(p); 981*95c635efSGarrett D'Amore break; 982*95c635efSGarrett D'Amore } 983*95c635efSGarrett D'Amore 984*95c635efSGarrett D'Amore /* 985*95c635efSGarrett D'Amore * Now that our output is flushed, we can reset our tags. Since 986*95c635efSGarrett D'Amore * only `It' sets these flags, we're free to assume that nobody 987*95c635efSGarrett D'Amore * has munged them in the meanwhile. 988*95c635efSGarrett D'Amore */ 989*95c635efSGarrett D'Amore 990*95c635efSGarrett D'Amore p->flags &= ~TERMP_DANGLE; 991*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 992*95c635efSGarrett D'Amore p->flags &= ~TERMP_TWOSPACE; 993*95c635efSGarrett D'Amore p->flags &= ~TERMP_HANG; 994*95c635efSGarrett D'Amore } 995*95c635efSGarrett D'Amore 996*95c635efSGarrett D'Amore 997*95c635efSGarrett D'Amore /* ARGSUSED */ 998*95c635efSGarrett D'Amore static int 999*95c635efSGarrett D'Amore termp_nm_pre(DECL_ARGS) 1000*95c635efSGarrett D'Amore { 1001*95c635efSGarrett D'Amore 1002*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) 1003*95c635efSGarrett D'Amore return(1); 1004*95c635efSGarrett D'Amore 1005*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) { 1006*95c635efSGarrett D'Amore if (NULL == n->child) 1007*95c635efSGarrett D'Amore return(0); 1008*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1009*95c635efSGarrett D'Amore p->offset += term_len(p, 1) + 1010*95c635efSGarrett D'Amore (NULL == n->prev->child ? term_strlen(p, m->name) : 1011*95c635efSGarrett D'Amore MDOC_TEXT == n->prev->child->type ? 1012*95c635efSGarrett D'Amore term_strlen(p, n->prev->child->string) : 1013*95c635efSGarrett D'Amore term_len(p, 5)); 1014*95c635efSGarrett D'Amore return(1); 1015*95c635efSGarrett D'Amore } 1016*95c635efSGarrett D'Amore 1017*95c635efSGarrett D'Amore if (NULL == n->child && NULL == m->name) 1018*95c635efSGarrett D'Amore return(0); 1019*95c635efSGarrett D'Amore 1020*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 1021*95c635efSGarrett D'Amore synopsis_pre(p, n->parent); 1022*95c635efSGarrett D'Amore 1023*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child) { 1024*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; 1025*95c635efSGarrett D'Amore p->rmargin = p->offset + term_len(p, 1); 1026*95c635efSGarrett D'Amore if (NULL == n->child) { 1027*95c635efSGarrett D'Amore p->rmargin += term_strlen(p, m->name); 1028*95c635efSGarrett D'Amore } else if (MDOC_TEXT == n->child->type) { 1029*95c635efSGarrett D'Amore p->rmargin += term_strlen(p, n->child->string); 1030*95c635efSGarrett D'Amore if (n->child->next) 1031*95c635efSGarrett D'Amore p->flags |= TERMP_HANG; 1032*95c635efSGarrett D'Amore } else { 1033*95c635efSGarrett D'Amore p->rmargin += term_len(p, 5); 1034*95c635efSGarrett D'Amore p->flags |= TERMP_HANG; 1035*95c635efSGarrett D'Amore } 1036*95c635efSGarrett D'Amore } 1037*95c635efSGarrett D'Amore 1038*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1039*95c635efSGarrett D'Amore if (NULL == n->child) 1040*95c635efSGarrett D'Amore term_word(p, m->name); 1041*95c635efSGarrett D'Amore return(1); 1042*95c635efSGarrett D'Amore } 1043*95c635efSGarrett D'Amore 1044*95c635efSGarrett D'Amore 1045*95c635efSGarrett D'Amore /* ARGSUSED */ 1046*95c635efSGarrett D'Amore static void 1047*95c635efSGarrett D'Amore termp_nm_post(DECL_ARGS) 1048*95c635efSGarrett D'Amore { 1049*95c635efSGarrett D'Amore 1050*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child) { 1051*95c635efSGarrett D'Amore term_flushln(p); 1052*95c635efSGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); 1053*95c635efSGarrett D'Amore } else if (MDOC_BODY == n->type && n->child) 1054*95c635efSGarrett D'Amore term_flushln(p); 1055*95c635efSGarrett D'Amore } 1056*95c635efSGarrett D'Amore 1057*95c635efSGarrett D'Amore 1058*95c635efSGarrett D'Amore /* ARGSUSED */ 1059*95c635efSGarrett D'Amore static int 1060*95c635efSGarrett D'Amore termp_fl_pre(DECL_ARGS) 1061*95c635efSGarrett D'Amore { 1062*95c635efSGarrett D'Amore 1063*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1064*95c635efSGarrett D'Amore term_word(p, "\\-"); 1065*95c635efSGarrett D'Amore 1066*95c635efSGarrett D'Amore if (n->child) 1067*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1068*95c635efSGarrett D'Amore else if (n->next && n->next->line == n->line) 1069*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1070*95c635efSGarrett D'Amore 1071*95c635efSGarrett D'Amore return(1); 1072*95c635efSGarrett D'Amore } 1073*95c635efSGarrett D'Amore 1074*95c635efSGarrett D'Amore 1075*95c635efSGarrett D'Amore /* ARGSUSED */ 1076*95c635efSGarrett D'Amore static int 1077*95c635efSGarrett D'Amore termp__a_pre(DECL_ARGS) 1078*95c635efSGarrett D'Amore { 1079*95c635efSGarrett D'Amore 1080*95c635efSGarrett D'Amore if (n->prev && MDOC__A == n->prev->tok) 1081*95c635efSGarrett D'Amore if (NULL == n->next || MDOC__A != n->next->tok) 1082*95c635efSGarrett D'Amore term_word(p, "and"); 1083*95c635efSGarrett D'Amore 1084*95c635efSGarrett D'Amore return(1); 1085*95c635efSGarrett D'Amore } 1086*95c635efSGarrett D'Amore 1087*95c635efSGarrett D'Amore 1088*95c635efSGarrett D'Amore /* ARGSUSED */ 1089*95c635efSGarrett D'Amore static int 1090*95c635efSGarrett D'Amore termp_an_pre(DECL_ARGS) 1091*95c635efSGarrett D'Amore { 1092*95c635efSGarrett D'Amore 1093*95c635efSGarrett D'Amore if (NULL == n->child) 1094*95c635efSGarrett D'Amore return(1); 1095*95c635efSGarrett D'Amore 1096*95c635efSGarrett D'Amore /* 1097*95c635efSGarrett D'Amore * If not in the AUTHORS section, `An -split' will cause 1098*95c635efSGarrett D'Amore * newlines to occur before the author name. If in the AUTHORS 1099*95c635efSGarrett D'Amore * section, by default, the first `An' invocation is nosplit, 1100*95c635efSGarrett D'Amore * then all subsequent ones, regardless of whether interspersed 1101*95c635efSGarrett D'Amore * with other macros/text, are split. -split, in this case, 1102*95c635efSGarrett D'Amore * will override the condition of the implied first -nosplit. 1103*95c635efSGarrett D'Amore */ 1104*95c635efSGarrett D'Amore 1105*95c635efSGarrett D'Amore if (n->sec == SEC_AUTHORS) { 1106*95c635efSGarrett D'Amore if ( ! (TERMP_ANPREC & p->flags)) { 1107*95c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags) 1108*95c635efSGarrett D'Amore term_newln(p); 1109*95c635efSGarrett D'Amore return(1); 1110*95c635efSGarrett D'Amore } 1111*95c635efSGarrett D'Amore if (TERMP_NOSPLIT & p->flags) 1112*95c635efSGarrett D'Amore return(1); 1113*95c635efSGarrett D'Amore term_newln(p); 1114*95c635efSGarrett D'Amore return(1); 1115*95c635efSGarrett D'Amore } 1116*95c635efSGarrett D'Amore 1117*95c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags) 1118*95c635efSGarrett D'Amore term_newln(p); 1119*95c635efSGarrett D'Amore 1120*95c635efSGarrett D'Amore return(1); 1121*95c635efSGarrett D'Amore } 1122*95c635efSGarrett D'Amore 1123*95c635efSGarrett D'Amore 1124*95c635efSGarrett D'Amore /* ARGSUSED */ 1125*95c635efSGarrett D'Amore static void 1126*95c635efSGarrett D'Amore termp_an_post(DECL_ARGS) 1127*95c635efSGarrett D'Amore { 1128*95c635efSGarrett D'Amore 1129*95c635efSGarrett D'Amore if (n->child) { 1130*95c635efSGarrett D'Amore if (SEC_AUTHORS == n->sec) 1131*95c635efSGarrett D'Amore p->flags |= TERMP_ANPREC; 1132*95c635efSGarrett D'Amore return; 1133*95c635efSGarrett D'Amore } 1134*95c635efSGarrett D'Amore 1135*95c635efSGarrett D'Amore if (AUTH_split == n->norm->An.auth) { 1136*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPLIT; 1137*95c635efSGarrett D'Amore p->flags |= TERMP_SPLIT; 1138*95c635efSGarrett D'Amore } else if (AUTH_nosplit == n->norm->An.auth) { 1139*95c635efSGarrett D'Amore p->flags &= ~TERMP_SPLIT; 1140*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPLIT; 1141*95c635efSGarrett D'Amore } 1142*95c635efSGarrett D'Amore 1143*95c635efSGarrett D'Amore } 1144*95c635efSGarrett D'Amore 1145*95c635efSGarrett D'Amore 1146*95c635efSGarrett D'Amore /* ARGSUSED */ 1147*95c635efSGarrett D'Amore static int 1148*95c635efSGarrett D'Amore termp_ns_pre(DECL_ARGS) 1149*95c635efSGarrett D'Amore { 1150*95c635efSGarrett D'Amore 1151*95c635efSGarrett D'Amore if ( ! (MDOC_LINE & n->flags)) 1152*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1153*95c635efSGarrett D'Amore return(1); 1154*95c635efSGarrett D'Amore } 1155*95c635efSGarrett D'Amore 1156*95c635efSGarrett D'Amore 1157*95c635efSGarrett D'Amore /* ARGSUSED */ 1158*95c635efSGarrett D'Amore static int 1159*95c635efSGarrett D'Amore termp_rs_pre(DECL_ARGS) 1160*95c635efSGarrett D'Amore { 1161*95c635efSGarrett D'Amore 1162*95c635efSGarrett D'Amore if (SEC_SEE_ALSO != n->sec) 1163*95c635efSGarrett D'Amore return(1); 1164*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type && n->prev) 1165*95c635efSGarrett D'Amore term_vspace(p); 1166*95c635efSGarrett D'Amore return(1); 1167*95c635efSGarrett D'Amore } 1168*95c635efSGarrett D'Amore 1169*95c635efSGarrett D'Amore 1170*95c635efSGarrett D'Amore /* ARGSUSED */ 1171*95c635efSGarrett D'Amore static int 1172*95c635efSGarrett D'Amore termp_rv_pre(DECL_ARGS) 1173*95c635efSGarrett D'Amore { 1174*95c635efSGarrett D'Amore int nchild; 1175*95c635efSGarrett D'Amore 1176*95c635efSGarrett D'Amore term_newln(p); 1177*95c635efSGarrett D'Amore term_word(p, "The"); 1178*95c635efSGarrett D'Amore 1179*95c635efSGarrett D'Amore nchild = n->nchild; 1180*95c635efSGarrett D'Amore for (n = n->child; n; n = n->next) { 1181*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1182*95c635efSGarrett D'Amore term_word(p, n->string); 1183*95c635efSGarrett D'Amore term_fontpop(p); 1184*95c635efSGarrett D'Amore 1185*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1186*95c635efSGarrett D'Amore term_word(p, "()"); 1187*95c635efSGarrett D'Amore 1188*95c635efSGarrett D'Amore if (nchild > 2 && n->next) { 1189*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1190*95c635efSGarrett D'Amore term_word(p, ","); 1191*95c635efSGarrett D'Amore } 1192*95c635efSGarrett D'Amore 1193*95c635efSGarrett D'Amore if (n->next && NULL == n->next->next) 1194*95c635efSGarrett D'Amore term_word(p, "and"); 1195*95c635efSGarrett D'Amore } 1196*95c635efSGarrett D'Amore 1197*95c635efSGarrett D'Amore if (nchild > 1) 1198*95c635efSGarrett D'Amore term_word(p, "functions return"); 1199*95c635efSGarrett D'Amore else 1200*95c635efSGarrett D'Amore term_word(p, "function returns"); 1201*95c635efSGarrett D'Amore 1202*95c635efSGarrett D'Amore term_word(p, "the value 0 if successful; otherwise the value " 1203*95c635efSGarrett D'Amore "-1 is returned and the global variable"); 1204*95c635efSGarrett D'Amore 1205*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1206*95c635efSGarrett D'Amore term_word(p, "errno"); 1207*95c635efSGarrett D'Amore term_fontpop(p); 1208*95c635efSGarrett D'Amore 1209*95c635efSGarrett D'Amore term_word(p, "is set to indicate the error."); 1210*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 1211*95c635efSGarrett D'Amore 1212*95c635efSGarrett D'Amore return(0); 1213*95c635efSGarrett D'Amore } 1214*95c635efSGarrett D'Amore 1215*95c635efSGarrett D'Amore 1216*95c635efSGarrett D'Amore /* ARGSUSED */ 1217*95c635efSGarrett D'Amore static int 1218*95c635efSGarrett D'Amore termp_ex_pre(DECL_ARGS) 1219*95c635efSGarrett D'Amore { 1220*95c635efSGarrett D'Amore int nchild; 1221*95c635efSGarrett D'Amore 1222*95c635efSGarrett D'Amore term_newln(p); 1223*95c635efSGarrett D'Amore term_word(p, "The"); 1224*95c635efSGarrett D'Amore 1225*95c635efSGarrett D'Amore nchild = n->nchild; 1226*95c635efSGarrett D'Amore for (n = n->child; n; n = n->next) { 1227*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1228*95c635efSGarrett D'Amore term_word(p, n->string); 1229*95c635efSGarrett D'Amore term_fontpop(p); 1230*95c635efSGarrett D'Amore 1231*95c635efSGarrett D'Amore if (nchild > 2 && n->next) { 1232*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1233*95c635efSGarrett D'Amore term_word(p, ","); 1234*95c635efSGarrett D'Amore } 1235*95c635efSGarrett D'Amore 1236*95c635efSGarrett D'Amore if (n->next && NULL == n->next->next) 1237*95c635efSGarrett D'Amore term_word(p, "and"); 1238*95c635efSGarrett D'Amore } 1239*95c635efSGarrett D'Amore 1240*95c635efSGarrett D'Amore if (nchild > 1) 1241*95c635efSGarrett D'Amore term_word(p, "utilities exit"); 1242*95c635efSGarrett D'Amore else 1243*95c635efSGarrett D'Amore term_word(p, "utility exits"); 1244*95c635efSGarrett D'Amore 1245*95c635efSGarrett D'Amore term_word(p, "0 on success, and >0 if an error occurs."); 1246*95c635efSGarrett D'Amore 1247*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 1248*95c635efSGarrett D'Amore return(0); 1249*95c635efSGarrett D'Amore } 1250*95c635efSGarrett D'Amore 1251*95c635efSGarrett D'Amore 1252*95c635efSGarrett D'Amore /* ARGSUSED */ 1253*95c635efSGarrett D'Amore static int 1254*95c635efSGarrett D'Amore termp_nd_pre(DECL_ARGS) 1255*95c635efSGarrett D'Amore { 1256*95c635efSGarrett D'Amore 1257*95c635efSGarrett D'Amore if (MDOC_BODY != n->type) 1258*95c635efSGarrett D'Amore return(1); 1259*95c635efSGarrett D'Amore 1260*95c635efSGarrett D'Amore #if defined(__OpenBSD__) || defined(__linux__) 1261*95c635efSGarrett D'Amore term_word(p, "\\(en"); 1262*95c635efSGarrett D'Amore #else 1263*95c635efSGarrett D'Amore term_word(p, "\\(em"); 1264*95c635efSGarrett D'Amore #endif 1265*95c635efSGarrett D'Amore return(1); 1266*95c635efSGarrett D'Amore } 1267*95c635efSGarrett D'Amore 1268*95c635efSGarrett D'Amore 1269*95c635efSGarrett D'Amore /* ARGSUSED */ 1270*95c635efSGarrett D'Amore static int 1271*95c635efSGarrett D'Amore termp_bl_pre(DECL_ARGS) 1272*95c635efSGarrett D'Amore { 1273*95c635efSGarrett D'Amore 1274*95c635efSGarrett D'Amore return(MDOC_HEAD != n->type); 1275*95c635efSGarrett D'Amore } 1276*95c635efSGarrett D'Amore 1277*95c635efSGarrett D'Amore 1278*95c635efSGarrett D'Amore /* ARGSUSED */ 1279*95c635efSGarrett D'Amore static void 1280*95c635efSGarrett D'Amore termp_bl_post(DECL_ARGS) 1281*95c635efSGarrett D'Amore { 1282*95c635efSGarrett D'Amore 1283*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) 1284*95c635efSGarrett D'Amore term_newln(p); 1285*95c635efSGarrett D'Amore } 1286*95c635efSGarrett D'Amore 1287*95c635efSGarrett D'Amore /* ARGSUSED */ 1288*95c635efSGarrett D'Amore static int 1289*95c635efSGarrett D'Amore termp_xr_pre(DECL_ARGS) 1290*95c635efSGarrett D'Amore { 1291*95c635efSGarrett D'Amore 1292*95c635efSGarrett D'Amore if (NULL == (n = n->child)) 1293*95c635efSGarrett D'Amore return(0); 1294*95c635efSGarrett D'Amore 1295*95c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 1296*95c635efSGarrett D'Amore term_word(p, n->string); 1297*95c635efSGarrett D'Amore 1298*95c635efSGarrett D'Amore if (NULL == (n = n->next)) 1299*95c635efSGarrett D'Amore return(0); 1300*95c635efSGarrett D'Amore 1301*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1302*95c635efSGarrett D'Amore term_word(p, "("); 1303*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1304*95c635efSGarrett D'Amore 1305*95c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 1306*95c635efSGarrett D'Amore term_word(p, n->string); 1307*95c635efSGarrett D'Amore 1308*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1309*95c635efSGarrett D'Amore term_word(p, ")"); 1310*95c635efSGarrett D'Amore 1311*95c635efSGarrett D'Amore return(0); 1312*95c635efSGarrett D'Amore } 1313*95c635efSGarrett D'Amore 1314*95c635efSGarrett D'Amore /* 1315*95c635efSGarrett D'Amore * This decides how to assert whitespace before any of the SYNOPSIS set 1316*95c635efSGarrett D'Amore * of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain 1317*95c635efSGarrett D'Amore * macro combos). 1318*95c635efSGarrett D'Amore */ 1319*95c635efSGarrett D'Amore static void 1320*95c635efSGarrett D'Amore synopsis_pre(struct termp *p, const struct mdoc_node *n) 1321*95c635efSGarrett D'Amore { 1322*95c635efSGarrett D'Amore /* 1323*95c635efSGarrett D'Amore * Obviously, if we're not in a SYNOPSIS or no prior macros 1324*95c635efSGarrett D'Amore * exist, do nothing. 1325*95c635efSGarrett D'Amore */ 1326*95c635efSGarrett D'Amore if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) 1327*95c635efSGarrett D'Amore return; 1328*95c635efSGarrett D'Amore 1329*95c635efSGarrett D'Amore /* 1330*95c635efSGarrett D'Amore * If we're the second in a pair of like elements, emit our 1331*95c635efSGarrett D'Amore * newline and return. UNLESS we're `Fo', `Fn', `Fn', in which 1332*95c635efSGarrett D'Amore * case we soldier on. 1333*95c635efSGarrett D'Amore */ 1334*95c635efSGarrett D'Amore if (n->prev->tok == n->tok && 1335*95c635efSGarrett D'Amore MDOC_Ft != n->tok && 1336*95c635efSGarrett D'Amore MDOC_Fo != n->tok && 1337*95c635efSGarrett D'Amore MDOC_Fn != n->tok) { 1338*95c635efSGarrett D'Amore term_newln(p); 1339*95c635efSGarrett D'Amore return; 1340*95c635efSGarrett D'Amore } 1341*95c635efSGarrett D'Amore 1342*95c635efSGarrett D'Amore /* 1343*95c635efSGarrett D'Amore * If we're one of the SYNOPSIS set and non-like pair-wise after 1344*95c635efSGarrett D'Amore * another (or Fn/Fo, which we've let slip through) then assert 1345*95c635efSGarrett D'Amore * vertical space, else only newline and move on. 1346*95c635efSGarrett D'Amore */ 1347*95c635efSGarrett D'Amore switch (n->prev->tok) { 1348*95c635efSGarrett D'Amore case (MDOC_Fd): 1349*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1350*95c635efSGarrett D'Amore case (MDOC_Fn): 1351*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1352*95c635efSGarrett D'Amore case (MDOC_Fo): 1353*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1354*95c635efSGarrett D'Amore case (MDOC_In): 1355*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1356*95c635efSGarrett D'Amore case (MDOC_Vt): 1357*95c635efSGarrett D'Amore term_vspace(p); 1358*95c635efSGarrett D'Amore break; 1359*95c635efSGarrett D'Amore case (MDOC_Ft): 1360*95c635efSGarrett D'Amore if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { 1361*95c635efSGarrett D'Amore term_vspace(p); 1362*95c635efSGarrett D'Amore break; 1363*95c635efSGarrett D'Amore } 1364*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1365*95c635efSGarrett D'Amore default: 1366*95c635efSGarrett D'Amore term_newln(p); 1367*95c635efSGarrett D'Amore break; 1368*95c635efSGarrett D'Amore } 1369*95c635efSGarrett D'Amore } 1370*95c635efSGarrett D'Amore 1371*95c635efSGarrett D'Amore 1372*95c635efSGarrett D'Amore static int 1373*95c635efSGarrett D'Amore termp_vt_pre(DECL_ARGS) 1374*95c635efSGarrett D'Amore { 1375*95c635efSGarrett D'Amore 1376*95c635efSGarrett D'Amore if (MDOC_ELEM == n->type) { 1377*95c635efSGarrett D'Amore synopsis_pre(p, n); 1378*95c635efSGarrett D'Amore return(termp_under_pre(p, pair, m, n)); 1379*95c635efSGarrett D'Amore } else if (MDOC_BLOCK == n->type) { 1380*95c635efSGarrett D'Amore synopsis_pre(p, n); 1381*95c635efSGarrett D'Amore return(1); 1382*95c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type) 1383*95c635efSGarrett D'Amore return(0); 1384*95c635efSGarrett D'Amore 1385*95c635efSGarrett D'Amore return(termp_under_pre(p, pair, m, n)); 1386*95c635efSGarrett D'Amore } 1387*95c635efSGarrett D'Amore 1388*95c635efSGarrett D'Amore 1389*95c635efSGarrett D'Amore /* ARGSUSED */ 1390*95c635efSGarrett D'Amore static int 1391*95c635efSGarrett D'Amore termp_bold_pre(DECL_ARGS) 1392*95c635efSGarrett D'Amore { 1393*95c635efSGarrett D'Amore 1394*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1395*95c635efSGarrett D'Amore return(1); 1396*95c635efSGarrett D'Amore } 1397*95c635efSGarrett D'Amore 1398*95c635efSGarrett D'Amore 1399*95c635efSGarrett D'Amore /* ARGSUSED */ 1400*95c635efSGarrett D'Amore static int 1401*95c635efSGarrett D'Amore termp_fd_pre(DECL_ARGS) 1402*95c635efSGarrett D'Amore { 1403*95c635efSGarrett D'Amore 1404*95c635efSGarrett D'Amore synopsis_pre(p, n); 1405*95c635efSGarrett D'Amore return(termp_bold_pre(p, pair, m, n)); 1406*95c635efSGarrett D'Amore } 1407*95c635efSGarrett D'Amore 1408*95c635efSGarrett D'Amore 1409*95c635efSGarrett D'Amore /* ARGSUSED */ 1410*95c635efSGarrett D'Amore static int 1411*95c635efSGarrett D'Amore termp_sh_pre(DECL_ARGS) 1412*95c635efSGarrett D'Amore { 1413*95c635efSGarrett D'Amore 1414*95c635efSGarrett D'Amore /* No vspace between consecutive `Sh' calls. */ 1415*95c635efSGarrett D'Amore 1416*95c635efSGarrett D'Amore switch (n->type) { 1417*95c635efSGarrett D'Amore case (MDOC_BLOCK): 1418*95c635efSGarrett D'Amore if (n->prev && MDOC_Sh == n->prev->tok) 1419*95c635efSGarrett D'Amore if (NULL == n->prev->body->child) 1420*95c635efSGarrett D'Amore break; 1421*95c635efSGarrett D'Amore term_vspace(p); 1422*95c635efSGarrett D'Amore break; 1423*95c635efSGarrett D'Amore case (MDOC_HEAD): 1424*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1425*95c635efSGarrett D'Amore break; 1426*95c635efSGarrett D'Amore case (MDOC_BODY): 1427*95c635efSGarrett D'Amore p->offset = term_len(p, p->defindent); 1428*95c635efSGarrett D'Amore break; 1429*95c635efSGarrett D'Amore default: 1430*95c635efSGarrett D'Amore break; 1431*95c635efSGarrett D'Amore } 1432*95c635efSGarrett D'Amore return(1); 1433*95c635efSGarrett D'Amore } 1434*95c635efSGarrett D'Amore 1435*95c635efSGarrett D'Amore 1436*95c635efSGarrett D'Amore /* ARGSUSED */ 1437*95c635efSGarrett D'Amore static void 1438*95c635efSGarrett D'Amore termp_sh_post(DECL_ARGS) 1439*95c635efSGarrett D'Amore { 1440*95c635efSGarrett D'Amore 1441*95c635efSGarrett D'Amore switch (n->type) { 1442*95c635efSGarrett D'Amore case (MDOC_HEAD): 1443*95c635efSGarrett D'Amore term_newln(p); 1444*95c635efSGarrett D'Amore break; 1445*95c635efSGarrett D'Amore case (MDOC_BODY): 1446*95c635efSGarrett D'Amore term_newln(p); 1447*95c635efSGarrett D'Amore p->offset = 0; 1448*95c635efSGarrett D'Amore break; 1449*95c635efSGarrett D'Amore default: 1450*95c635efSGarrett D'Amore break; 1451*95c635efSGarrett D'Amore } 1452*95c635efSGarrett D'Amore } 1453*95c635efSGarrett D'Amore 1454*95c635efSGarrett D'Amore 1455*95c635efSGarrett D'Amore /* ARGSUSED */ 1456*95c635efSGarrett D'Amore static int 1457*95c635efSGarrett D'Amore termp_bt_pre(DECL_ARGS) 1458*95c635efSGarrett D'Amore { 1459*95c635efSGarrett D'Amore 1460*95c635efSGarrett D'Amore term_word(p, "is currently in beta test."); 1461*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 1462*95c635efSGarrett D'Amore return(0); 1463*95c635efSGarrett D'Amore } 1464*95c635efSGarrett D'Amore 1465*95c635efSGarrett D'Amore 1466*95c635efSGarrett D'Amore /* ARGSUSED */ 1467*95c635efSGarrett D'Amore static void 1468*95c635efSGarrett D'Amore termp_lb_post(DECL_ARGS) 1469*95c635efSGarrett D'Amore { 1470*95c635efSGarrett D'Amore 1471*95c635efSGarrett D'Amore if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags) 1472*95c635efSGarrett D'Amore term_newln(p); 1473*95c635efSGarrett D'Amore } 1474*95c635efSGarrett D'Amore 1475*95c635efSGarrett D'Amore 1476*95c635efSGarrett D'Amore /* ARGSUSED */ 1477*95c635efSGarrett D'Amore static int 1478*95c635efSGarrett D'Amore termp_ud_pre(DECL_ARGS) 1479*95c635efSGarrett D'Amore { 1480*95c635efSGarrett D'Amore 1481*95c635efSGarrett D'Amore term_word(p, "currently under development."); 1482*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 1483*95c635efSGarrett D'Amore return(0); 1484*95c635efSGarrett D'Amore } 1485*95c635efSGarrett D'Amore 1486*95c635efSGarrett D'Amore 1487*95c635efSGarrett D'Amore /* ARGSUSED */ 1488*95c635efSGarrett D'Amore static int 1489*95c635efSGarrett D'Amore termp_d1_pre(DECL_ARGS) 1490*95c635efSGarrett D'Amore { 1491*95c635efSGarrett D'Amore 1492*95c635efSGarrett D'Amore if (MDOC_BLOCK != n->type) 1493*95c635efSGarrett D'Amore return(1); 1494*95c635efSGarrett D'Amore term_newln(p); 1495*95c635efSGarrett D'Amore p->offset += term_len(p, p->defindent + 1); 1496*95c635efSGarrett D'Amore return(1); 1497*95c635efSGarrett D'Amore } 1498*95c635efSGarrett D'Amore 1499*95c635efSGarrett D'Amore 1500*95c635efSGarrett D'Amore /* ARGSUSED */ 1501*95c635efSGarrett D'Amore static void 1502*95c635efSGarrett D'Amore termp_d1_post(DECL_ARGS) 1503*95c635efSGarrett D'Amore { 1504*95c635efSGarrett D'Amore 1505*95c635efSGarrett D'Amore if (MDOC_BLOCK != n->type) 1506*95c635efSGarrett D'Amore return; 1507*95c635efSGarrett D'Amore term_newln(p); 1508*95c635efSGarrett D'Amore } 1509*95c635efSGarrett D'Amore 1510*95c635efSGarrett D'Amore 1511*95c635efSGarrett D'Amore /* ARGSUSED */ 1512*95c635efSGarrett D'Amore static int 1513*95c635efSGarrett D'Amore termp_ft_pre(DECL_ARGS) 1514*95c635efSGarrett D'Amore { 1515*95c635efSGarrett D'Amore 1516*95c635efSGarrett D'Amore /* NB: MDOC_LINE does not effect this! */ 1517*95c635efSGarrett D'Amore synopsis_pre(p, n); 1518*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1519*95c635efSGarrett D'Amore return(1); 1520*95c635efSGarrett D'Amore } 1521*95c635efSGarrett D'Amore 1522*95c635efSGarrett D'Amore 1523*95c635efSGarrett D'Amore /* ARGSUSED */ 1524*95c635efSGarrett D'Amore static int 1525*95c635efSGarrett D'Amore termp_fn_pre(DECL_ARGS) 1526*95c635efSGarrett D'Amore { 1527*95c635efSGarrett D'Amore int pretty; 1528*95c635efSGarrett D'Amore 1529*95c635efSGarrett D'Amore pretty = MDOC_SYNPRETTY & n->flags; 1530*95c635efSGarrett D'Amore 1531*95c635efSGarrett D'Amore synopsis_pre(p, n); 1532*95c635efSGarrett D'Amore 1533*95c635efSGarrett D'Amore if (NULL == (n = n->child)) 1534*95c635efSGarrett D'Amore return(0); 1535*95c635efSGarrett D'Amore 1536*95c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 1537*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1538*95c635efSGarrett D'Amore term_word(p, n->string); 1539*95c635efSGarrett D'Amore term_fontpop(p); 1540*95c635efSGarrett D'Amore 1541*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1542*95c635efSGarrett D'Amore term_word(p, "("); 1543*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1544*95c635efSGarrett D'Amore 1545*95c635efSGarrett D'Amore for (n = n->next; n; n = n->next) { 1546*95c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 1547*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1548*95c635efSGarrett D'Amore term_word(p, n->string); 1549*95c635efSGarrett D'Amore term_fontpop(p); 1550*95c635efSGarrett D'Amore 1551*95c635efSGarrett D'Amore if (n->next) { 1552*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1553*95c635efSGarrett D'Amore term_word(p, ","); 1554*95c635efSGarrett D'Amore } 1555*95c635efSGarrett D'Amore } 1556*95c635efSGarrett D'Amore 1557*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1558*95c635efSGarrett D'Amore term_word(p, ")"); 1559*95c635efSGarrett D'Amore 1560*95c635efSGarrett D'Amore if (pretty) { 1561*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1562*95c635efSGarrett D'Amore term_word(p, ";"); 1563*95c635efSGarrett D'Amore } 1564*95c635efSGarrett D'Amore 1565*95c635efSGarrett D'Amore return(0); 1566*95c635efSGarrett D'Amore } 1567*95c635efSGarrett D'Amore 1568*95c635efSGarrett D'Amore 1569*95c635efSGarrett D'Amore /* ARGSUSED */ 1570*95c635efSGarrett D'Amore static int 1571*95c635efSGarrett D'Amore termp_fa_pre(DECL_ARGS) 1572*95c635efSGarrett D'Amore { 1573*95c635efSGarrett D'Amore const struct mdoc_node *nn; 1574*95c635efSGarrett D'Amore 1575*95c635efSGarrett D'Amore if (n->parent->tok != MDOC_Fo) { 1576*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1577*95c635efSGarrett D'Amore return(1); 1578*95c635efSGarrett D'Amore } 1579*95c635efSGarrett D'Amore 1580*95c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) { 1581*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1582*95c635efSGarrett D'Amore term_word(p, nn->string); 1583*95c635efSGarrett D'Amore term_fontpop(p); 1584*95c635efSGarrett D'Amore 1585*95c635efSGarrett D'Amore if (nn->next) { 1586*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1587*95c635efSGarrett D'Amore term_word(p, ","); 1588*95c635efSGarrett D'Amore } 1589*95c635efSGarrett D'Amore } 1590*95c635efSGarrett D'Amore 1591*95c635efSGarrett D'Amore if (n->child && n->next && n->next->tok == MDOC_Fa) { 1592*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1593*95c635efSGarrett D'Amore term_word(p, ","); 1594*95c635efSGarrett D'Amore } 1595*95c635efSGarrett D'Amore 1596*95c635efSGarrett D'Amore return(0); 1597*95c635efSGarrett D'Amore } 1598*95c635efSGarrett D'Amore 1599*95c635efSGarrett D'Amore 1600*95c635efSGarrett D'Amore /* ARGSUSED */ 1601*95c635efSGarrett D'Amore static int 1602*95c635efSGarrett D'Amore termp_bd_pre(DECL_ARGS) 1603*95c635efSGarrett D'Amore { 1604*95c635efSGarrett D'Amore size_t tabwidth, rm, rmax; 1605*95c635efSGarrett D'Amore const struct mdoc_node *nn; 1606*95c635efSGarrett D'Amore 1607*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 1608*95c635efSGarrett D'Amore print_bvspace(p, n, n); 1609*95c635efSGarrett D'Amore return(1); 1610*95c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type) 1611*95c635efSGarrett D'Amore return(0); 1612*95c635efSGarrett D'Amore 1613*95c635efSGarrett D'Amore if (n->norm->Bd.offs) 1614*95c635efSGarrett D'Amore p->offset += a2offs(p, n->norm->Bd.offs); 1615*95c635efSGarrett D'Amore 1616*95c635efSGarrett D'Amore /* 1617*95c635efSGarrett D'Amore * If -ragged or -filled are specified, the block does nothing 1618*95c635efSGarrett D'Amore * but change the indentation. If -unfilled or -literal are 1619*95c635efSGarrett D'Amore * specified, text is printed exactly as entered in the display: 1620*95c635efSGarrett D'Amore * for macro lines, a newline is appended to the line. Blank 1621*95c635efSGarrett D'Amore * lines are allowed. 1622*95c635efSGarrett D'Amore */ 1623*95c635efSGarrett D'Amore 1624*95c635efSGarrett D'Amore if (DISP_literal != n->norm->Bd.type && 1625*95c635efSGarrett D'Amore DISP_unfilled != n->norm->Bd.type) 1626*95c635efSGarrett D'Amore return(1); 1627*95c635efSGarrett D'Amore 1628*95c635efSGarrett D'Amore tabwidth = p->tabwidth; 1629*95c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type) 1630*95c635efSGarrett D'Amore p->tabwidth = term_len(p, 8); 1631*95c635efSGarrett D'Amore 1632*95c635efSGarrett D'Amore rm = p->rmargin; 1633*95c635efSGarrett D'Amore rmax = p->maxrmargin; 1634*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN; 1635*95c635efSGarrett D'Amore 1636*95c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) { 1637*95c635efSGarrett D'Amore print_mdoc_node(p, pair, m, nn); 1638*95c635efSGarrett D'Amore /* 1639*95c635efSGarrett D'Amore * If the printed node flushes its own line, then we 1640*95c635efSGarrett D'Amore * needn't do it here as well. This is hacky, but the 1641*95c635efSGarrett D'Amore * notion of selective eoln whitespace is pretty dumb 1642*95c635efSGarrett D'Amore * anyway, so don't sweat it. 1643*95c635efSGarrett D'Amore */ 1644*95c635efSGarrett D'Amore switch (nn->tok) { 1645*95c635efSGarrett D'Amore case (MDOC_Sm): 1646*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1647*95c635efSGarrett D'Amore case (MDOC_br): 1648*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1649*95c635efSGarrett D'Amore case (MDOC_sp): 1650*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1651*95c635efSGarrett D'Amore case (MDOC_Bl): 1652*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1653*95c635efSGarrett D'Amore case (MDOC_D1): 1654*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1655*95c635efSGarrett D'Amore case (MDOC_Dl): 1656*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1657*95c635efSGarrett D'Amore case (MDOC_Lp): 1658*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1659*95c635efSGarrett D'Amore case (MDOC_Pp): 1660*95c635efSGarrett D'Amore continue; 1661*95c635efSGarrett D'Amore default: 1662*95c635efSGarrett D'Amore break; 1663*95c635efSGarrett D'Amore } 1664*95c635efSGarrett D'Amore if (nn->next && nn->next->line == nn->line) 1665*95c635efSGarrett D'Amore continue; 1666*95c635efSGarrett D'Amore term_flushln(p); 1667*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1668*95c635efSGarrett D'Amore } 1669*95c635efSGarrett D'Amore 1670*95c635efSGarrett D'Amore p->tabwidth = tabwidth; 1671*95c635efSGarrett D'Amore p->rmargin = rm; 1672*95c635efSGarrett D'Amore p->maxrmargin = rmax; 1673*95c635efSGarrett D'Amore return(0); 1674*95c635efSGarrett D'Amore } 1675*95c635efSGarrett D'Amore 1676*95c635efSGarrett D'Amore 1677*95c635efSGarrett D'Amore /* ARGSUSED */ 1678*95c635efSGarrett D'Amore static void 1679*95c635efSGarrett D'Amore termp_bd_post(DECL_ARGS) 1680*95c635efSGarrett D'Amore { 1681*95c635efSGarrett D'Amore size_t rm, rmax; 1682*95c635efSGarrett D'Amore 1683*95c635efSGarrett D'Amore if (MDOC_BODY != n->type) 1684*95c635efSGarrett D'Amore return; 1685*95c635efSGarrett D'Amore 1686*95c635efSGarrett D'Amore rm = p->rmargin; 1687*95c635efSGarrett D'Amore rmax = p->maxrmargin; 1688*95c635efSGarrett D'Amore 1689*95c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type || 1690*95c635efSGarrett D'Amore DISP_unfilled == n->norm->Bd.type) 1691*95c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN; 1692*95c635efSGarrett D'Amore 1693*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1694*95c635efSGarrett D'Amore term_newln(p); 1695*95c635efSGarrett D'Amore 1696*95c635efSGarrett D'Amore p->rmargin = rm; 1697*95c635efSGarrett D'Amore p->maxrmargin = rmax; 1698*95c635efSGarrett D'Amore } 1699*95c635efSGarrett D'Amore 1700*95c635efSGarrett D'Amore 1701*95c635efSGarrett D'Amore /* ARGSUSED */ 1702*95c635efSGarrett D'Amore static int 1703*95c635efSGarrett D'Amore termp_bx_pre(DECL_ARGS) 1704*95c635efSGarrett D'Amore { 1705*95c635efSGarrett D'Amore 1706*95c635efSGarrett D'Amore if (NULL != (n = n->child)) { 1707*95c635efSGarrett D'Amore term_word(p, n->string); 1708*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1709*95c635efSGarrett D'Amore term_word(p, "BSD"); 1710*95c635efSGarrett D'Amore } else { 1711*95c635efSGarrett D'Amore term_word(p, "BSD"); 1712*95c635efSGarrett D'Amore return(0); 1713*95c635efSGarrett D'Amore } 1714*95c635efSGarrett D'Amore 1715*95c635efSGarrett D'Amore if (NULL != (n = n->next)) { 1716*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1717*95c635efSGarrett D'Amore term_word(p, "-"); 1718*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1719*95c635efSGarrett D'Amore term_word(p, n->string); 1720*95c635efSGarrett D'Amore } 1721*95c635efSGarrett D'Amore 1722*95c635efSGarrett D'Amore return(0); 1723*95c635efSGarrett D'Amore } 1724*95c635efSGarrett D'Amore 1725*95c635efSGarrett D'Amore 1726*95c635efSGarrett D'Amore /* ARGSUSED */ 1727*95c635efSGarrett D'Amore static int 1728*95c635efSGarrett D'Amore termp_xx_pre(DECL_ARGS) 1729*95c635efSGarrett D'Amore { 1730*95c635efSGarrett D'Amore const char *pp; 1731*95c635efSGarrett D'Amore int flags; 1732*95c635efSGarrett D'Amore 1733*95c635efSGarrett D'Amore pp = NULL; 1734*95c635efSGarrett D'Amore switch (n->tok) { 1735*95c635efSGarrett D'Amore case (MDOC_Bsx): 1736*95c635efSGarrett D'Amore pp = "BSD/OS"; 1737*95c635efSGarrett D'Amore break; 1738*95c635efSGarrett D'Amore case (MDOC_Dx): 1739*95c635efSGarrett D'Amore pp = "DragonFly"; 1740*95c635efSGarrett D'Amore break; 1741*95c635efSGarrett D'Amore case (MDOC_Fx): 1742*95c635efSGarrett D'Amore pp = "FreeBSD"; 1743*95c635efSGarrett D'Amore break; 1744*95c635efSGarrett D'Amore case (MDOC_Nx): 1745*95c635efSGarrett D'Amore pp = "NetBSD"; 1746*95c635efSGarrett D'Amore break; 1747*95c635efSGarrett D'Amore case (MDOC_Ox): 1748*95c635efSGarrett D'Amore pp = "OpenBSD"; 1749*95c635efSGarrett D'Amore break; 1750*95c635efSGarrett D'Amore case (MDOC_Ux): 1751*95c635efSGarrett D'Amore pp = "UNIX"; 1752*95c635efSGarrett D'Amore break; 1753*95c635efSGarrett D'Amore default: 1754*95c635efSGarrett D'Amore break; 1755*95c635efSGarrett D'Amore } 1756*95c635efSGarrett D'Amore 1757*95c635efSGarrett D'Amore term_word(p, pp); 1758*95c635efSGarrett D'Amore if (n->child) { 1759*95c635efSGarrett D'Amore flags = p->flags; 1760*95c635efSGarrett D'Amore p->flags |= TERMP_KEEP; 1761*95c635efSGarrett D'Amore term_word(p, n->child->string); 1762*95c635efSGarrett D'Amore p->flags = flags; 1763*95c635efSGarrett D'Amore } 1764*95c635efSGarrett D'Amore return(0); 1765*95c635efSGarrett D'Amore } 1766*95c635efSGarrett D'Amore 1767*95c635efSGarrett D'Amore 1768*95c635efSGarrett D'Amore /* ARGSUSED */ 1769*95c635efSGarrett D'Amore static int 1770*95c635efSGarrett D'Amore termp_igndelim_pre(DECL_ARGS) 1771*95c635efSGarrett D'Amore { 1772*95c635efSGarrett D'Amore 1773*95c635efSGarrett D'Amore p->flags |= TERMP_IGNDELIM; 1774*95c635efSGarrett D'Amore return(1); 1775*95c635efSGarrett D'Amore } 1776*95c635efSGarrett D'Amore 1777*95c635efSGarrett D'Amore 1778*95c635efSGarrett D'Amore /* ARGSUSED */ 1779*95c635efSGarrett D'Amore static void 1780*95c635efSGarrett D'Amore termp_pf_post(DECL_ARGS) 1781*95c635efSGarrett D'Amore { 1782*95c635efSGarrett D'Amore 1783*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1784*95c635efSGarrett D'Amore } 1785*95c635efSGarrett D'Amore 1786*95c635efSGarrett D'Amore 1787*95c635efSGarrett D'Amore /* ARGSUSED */ 1788*95c635efSGarrett D'Amore static int 1789*95c635efSGarrett D'Amore termp_ss_pre(DECL_ARGS) 1790*95c635efSGarrett D'Amore { 1791*95c635efSGarrett D'Amore 1792*95c635efSGarrett D'Amore switch (n->type) { 1793*95c635efSGarrett D'Amore case (MDOC_BLOCK): 1794*95c635efSGarrett D'Amore term_newln(p); 1795*95c635efSGarrett D'Amore if (n->prev) 1796*95c635efSGarrett D'Amore term_vspace(p); 1797*95c635efSGarrett D'Amore break; 1798*95c635efSGarrett D'Amore case (MDOC_HEAD): 1799*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1800*95c635efSGarrett D'Amore p->offset = term_len(p, (p->defindent+1)/2); 1801*95c635efSGarrett D'Amore break; 1802*95c635efSGarrett D'Amore default: 1803*95c635efSGarrett D'Amore break; 1804*95c635efSGarrett D'Amore } 1805*95c635efSGarrett D'Amore 1806*95c635efSGarrett D'Amore return(1); 1807*95c635efSGarrett D'Amore } 1808*95c635efSGarrett D'Amore 1809*95c635efSGarrett D'Amore 1810*95c635efSGarrett D'Amore /* ARGSUSED */ 1811*95c635efSGarrett D'Amore static void 1812*95c635efSGarrett D'Amore termp_ss_post(DECL_ARGS) 1813*95c635efSGarrett D'Amore { 1814*95c635efSGarrett D'Amore 1815*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 1816*95c635efSGarrett D'Amore term_newln(p); 1817*95c635efSGarrett D'Amore } 1818*95c635efSGarrett D'Amore 1819*95c635efSGarrett D'Amore 1820*95c635efSGarrett D'Amore /* ARGSUSED */ 1821*95c635efSGarrett D'Amore static int 1822*95c635efSGarrett D'Amore termp_cd_pre(DECL_ARGS) 1823*95c635efSGarrett D'Amore { 1824*95c635efSGarrett D'Amore 1825*95c635efSGarrett D'Amore synopsis_pre(p, n); 1826*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1827*95c635efSGarrett D'Amore return(1); 1828*95c635efSGarrett D'Amore } 1829*95c635efSGarrett D'Amore 1830*95c635efSGarrett D'Amore 1831*95c635efSGarrett D'Amore /* ARGSUSED */ 1832*95c635efSGarrett D'Amore static int 1833*95c635efSGarrett D'Amore termp_in_pre(DECL_ARGS) 1834*95c635efSGarrett D'Amore { 1835*95c635efSGarrett D'Amore 1836*95c635efSGarrett D'Amore synopsis_pre(p, n); 1837*95c635efSGarrett D'Amore 1838*95c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) { 1839*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1840*95c635efSGarrett D'Amore term_word(p, "#include"); 1841*95c635efSGarrett D'Amore term_word(p, "<"); 1842*95c635efSGarrett D'Amore } else { 1843*95c635efSGarrett D'Amore term_word(p, "<"); 1844*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1845*95c635efSGarrett D'Amore } 1846*95c635efSGarrett D'Amore 1847*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1848*95c635efSGarrett D'Amore return(1); 1849*95c635efSGarrett D'Amore } 1850*95c635efSGarrett D'Amore 1851*95c635efSGarrett D'Amore 1852*95c635efSGarrett D'Amore /* ARGSUSED */ 1853*95c635efSGarrett D'Amore static void 1854*95c635efSGarrett D'Amore termp_in_post(DECL_ARGS) 1855*95c635efSGarrett D'Amore { 1856*95c635efSGarrett D'Amore 1857*95c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) 1858*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 1859*95c635efSGarrett D'Amore 1860*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1861*95c635efSGarrett D'Amore term_word(p, ">"); 1862*95c635efSGarrett D'Amore 1863*95c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) 1864*95c635efSGarrett D'Amore term_fontpop(p); 1865*95c635efSGarrett D'Amore } 1866*95c635efSGarrett D'Amore 1867*95c635efSGarrett D'Amore 1868*95c635efSGarrett D'Amore /* ARGSUSED */ 1869*95c635efSGarrett D'Amore static int 1870*95c635efSGarrett D'Amore termp_sp_pre(DECL_ARGS) 1871*95c635efSGarrett D'Amore { 1872*95c635efSGarrett D'Amore size_t i, len; 1873*95c635efSGarrett D'Amore 1874*95c635efSGarrett D'Amore switch (n->tok) { 1875*95c635efSGarrett D'Amore case (MDOC_sp): 1876*95c635efSGarrett D'Amore len = n->child ? a2height(p, n->child->string) : 1; 1877*95c635efSGarrett D'Amore break; 1878*95c635efSGarrett D'Amore case (MDOC_br): 1879*95c635efSGarrett D'Amore len = 0; 1880*95c635efSGarrett D'Amore break; 1881*95c635efSGarrett D'Amore default: 1882*95c635efSGarrett D'Amore len = 1; 1883*95c635efSGarrett D'Amore break; 1884*95c635efSGarrett D'Amore } 1885*95c635efSGarrett D'Amore 1886*95c635efSGarrett D'Amore if (0 == len) 1887*95c635efSGarrett D'Amore term_newln(p); 1888*95c635efSGarrett D'Amore for (i = 0; i < len; i++) 1889*95c635efSGarrett D'Amore term_vspace(p); 1890*95c635efSGarrett D'Amore 1891*95c635efSGarrett D'Amore return(0); 1892*95c635efSGarrett D'Amore } 1893*95c635efSGarrett D'Amore 1894*95c635efSGarrett D'Amore 1895*95c635efSGarrett D'Amore /* ARGSUSED */ 1896*95c635efSGarrett D'Amore static int 1897*95c635efSGarrett D'Amore termp_quote_pre(DECL_ARGS) 1898*95c635efSGarrett D'Amore { 1899*95c635efSGarrett D'Amore 1900*95c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type) 1901*95c635efSGarrett D'Amore return(1); 1902*95c635efSGarrett D'Amore 1903*95c635efSGarrett D'Amore switch (n->tok) { 1904*95c635efSGarrett D'Amore case (MDOC_Ao): 1905*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1906*95c635efSGarrett D'Amore case (MDOC_Aq): 1907*95c635efSGarrett D'Amore term_word(p, "<"); 1908*95c635efSGarrett D'Amore break; 1909*95c635efSGarrett D'Amore case (MDOC_Bro): 1910*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1911*95c635efSGarrett D'Amore case (MDOC_Brq): 1912*95c635efSGarrett D'Amore term_word(p, "{"); 1913*95c635efSGarrett D'Amore break; 1914*95c635efSGarrett D'Amore case (MDOC_Oo): 1915*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1916*95c635efSGarrett D'Amore case (MDOC_Op): 1917*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1918*95c635efSGarrett D'Amore case (MDOC_Bo): 1919*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1920*95c635efSGarrett D'Amore case (MDOC_Bq): 1921*95c635efSGarrett D'Amore term_word(p, "["); 1922*95c635efSGarrett D'Amore break; 1923*95c635efSGarrett D'Amore case (MDOC_Do): 1924*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1925*95c635efSGarrett D'Amore case (MDOC_Dq): 1926*95c635efSGarrett D'Amore term_word(p, "``"); 1927*95c635efSGarrett D'Amore break; 1928*95c635efSGarrett D'Amore case (MDOC_Eo): 1929*95c635efSGarrett D'Amore break; 1930*95c635efSGarrett D'Amore case (MDOC_Po): 1931*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1932*95c635efSGarrett D'Amore case (MDOC_Pq): 1933*95c635efSGarrett D'Amore term_word(p, "("); 1934*95c635efSGarrett D'Amore break; 1935*95c635efSGarrett D'Amore case (MDOC__T): 1936*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1937*95c635efSGarrett D'Amore case (MDOC_Qo): 1938*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1939*95c635efSGarrett D'Amore case (MDOC_Qq): 1940*95c635efSGarrett D'Amore term_word(p, "\""); 1941*95c635efSGarrett D'Amore break; 1942*95c635efSGarrett D'Amore case (MDOC_Ql): 1943*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1944*95c635efSGarrett D'Amore case (MDOC_So): 1945*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1946*95c635efSGarrett D'Amore case (MDOC_Sq): 1947*95c635efSGarrett D'Amore term_word(p, "`"); 1948*95c635efSGarrett D'Amore break; 1949*95c635efSGarrett D'Amore default: 1950*95c635efSGarrett D'Amore abort(); 1951*95c635efSGarrett D'Amore /* NOTREACHED */ 1952*95c635efSGarrett D'Amore } 1953*95c635efSGarrett D'Amore 1954*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1955*95c635efSGarrett D'Amore return(1); 1956*95c635efSGarrett D'Amore } 1957*95c635efSGarrett D'Amore 1958*95c635efSGarrett D'Amore 1959*95c635efSGarrett D'Amore /* ARGSUSED */ 1960*95c635efSGarrett D'Amore static void 1961*95c635efSGarrett D'Amore termp_quote_post(DECL_ARGS) 1962*95c635efSGarrett D'Amore { 1963*95c635efSGarrett D'Amore 1964*95c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type) 1965*95c635efSGarrett D'Amore return; 1966*95c635efSGarrett D'Amore 1967*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 1968*95c635efSGarrett D'Amore 1969*95c635efSGarrett D'Amore switch (n->tok) { 1970*95c635efSGarrett D'Amore case (MDOC_Ao): 1971*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1972*95c635efSGarrett D'Amore case (MDOC_Aq): 1973*95c635efSGarrett D'Amore term_word(p, ">"); 1974*95c635efSGarrett D'Amore break; 1975*95c635efSGarrett D'Amore case (MDOC_Bro): 1976*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1977*95c635efSGarrett D'Amore case (MDOC_Brq): 1978*95c635efSGarrett D'Amore term_word(p, "}"); 1979*95c635efSGarrett D'Amore break; 1980*95c635efSGarrett D'Amore case (MDOC_Oo): 1981*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1982*95c635efSGarrett D'Amore case (MDOC_Op): 1983*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1984*95c635efSGarrett D'Amore case (MDOC_Bo): 1985*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1986*95c635efSGarrett D'Amore case (MDOC_Bq): 1987*95c635efSGarrett D'Amore term_word(p, "]"); 1988*95c635efSGarrett D'Amore break; 1989*95c635efSGarrett D'Amore case (MDOC_Do): 1990*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1991*95c635efSGarrett D'Amore case (MDOC_Dq): 1992*95c635efSGarrett D'Amore term_word(p, "''"); 1993*95c635efSGarrett D'Amore break; 1994*95c635efSGarrett D'Amore case (MDOC_Eo): 1995*95c635efSGarrett D'Amore break; 1996*95c635efSGarrett D'Amore case (MDOC_Po): 1997*95c635efSGarrett D'Amore /* FALLTHROUGH */ 1998*95c635efSGarrett D'Amore case (MDOC_Pq): 1999*95c635efSGarrett D'Amore term_word(p, ")"); 2000*95c635efSGarrett D'Amore break; 2001*95c635efSGarrett D'Amore case (MDOC__T): 2002*95c635efSGarrett D'Amore /* FALLTHROUGH */ 2003*95c635efSGarrett D'Amore case (MDOC_Qo): 2004*95c635efSGarrett D'Amore /* FALLTHROUGH */ 2005*95c635efSGarrett D'Amore case (MDOC_Qq): 2006*95c635efSGarrett D'Amore term_word(p, "\""); 2007*95c635efSGarrett D'Amore break; 2008*95c635efSGarrett D'Amore case (MDOC_Ql): 2009*95c635efSGarrett D'Amore /* FALLTHROUGH */ 2010*95c635efSGarrett D'Amore case (MDOC_So): 2011*95c635efSGarrett D'Amore /* FALLTHROUGH */ 2012*95c635efSGarrett D'Amore case (MDOC_Sq): 2013*95c635efSGarrett D'Amore term_word(p, "'"); 2014*95c635efSGarrett D'Amore break; 2015*95c635efSGarrett D'Amore default: 2016*95c635efSGarrett D'Amore abort(); 2017*95c635efSGarrett D'Amore /* NOTREACHED */ 2018*95c635efSGarrett D'Amore } 2019*95c635efSGarrett D'Amore } 2020*95c635efSGarrett D'Amore 2021*95c635efSGarrett D'Amore 2022*95c635efSGarrett D'Amore /* ARGSUSED */ 2023*95c635efSGarrett D'Amore static int 2024*95c635efSGarrett D'Amore termp_fo_pre(DECL_ARGS) 2025*95c635efSGarrett D'Amore { 2026*95c635efSGarrett D'Amore 2027*95c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 2028*95c635efSGarrett D'Amore synopsis_pre(p, n); 2029*95c635efSGarrett D'Amore return(1); 2030*95c635efSGarrett D'Amore } else if (MDOC_BODY == n->type) { 2031*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2032*95c635efSGarrett D'Amore term_word(p, "("); 2033*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2034*95c635efSGarrett D'Amore return(1); 2035*95c635efSGarrett D'Amore } 2036*95c635efSGarrett D'Amore 2037*95c635efSGarrett D'Amore if (NULL == n->child) 2038*95c635efSGarrett D'Amore return(0); 2039*95c635efSGarrett D'Amore 2040*95c635efSGarrett D'Amore /* XXX: we drop non-initial arguments as per groff. */ 2041*95c635efSGarrett D'Amore 2042*95c635efSGarrett D'Amore assert(n->child->string); 2043*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 2044*95c635efSGarrett D'Amore term_word(p, n->child->string); 2045*95c635efSGarrett D'Amore return(0); 2046*95c635efSGarrett D'Amore } 2047*95c635efSGarrett D'Amore 2048*95c635efSGarrett D'Amore 2049*95c635efSGarrett D'Amore /* ARGSUSED */ 2050*95c635efSGarrett D'Amore static void 2051*95c635efSGarrett D'Amore termp_fo_post(DECL_ARGS) 2052*95c635efSGarrett D'Amore { 2053*95c635efSGarrett D'Amore 2054*95c635efSGarrett D'Amore if (MDOC_BODY != n->type) 2055*95c635efSGarrett D'Amore return; 2056*95c635efSGarrett D'Amore 2057*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2058*95c635efSGarrett D'Amore term_word(p, ")"); 2059*95c635efSGarrett D'Amore 2060*95c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) { 2061*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2062*95c635efSGarrett D'Amore term_word(p, ";"); 2063*95c635efSGarrett D'Amore } 2064*95c635efSGarrett D'Amore } 2065*95c635efSGarrett D'Amore 2066*95c635efSGarrett D'Amore 2067*95c635efSGarrett D'Amore /* ARGSUSED */ 2068*95c635efSGarrett D'Amore static int 2069*95c635efSGarrett D'Amore termp_bf_pre(DECL_ARGS) 2070*95c635efSGarrett D'Amore { 2071*95c635efSGarrett D'Amore 2072*95c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 2073*95c635efSGarrett D'Amore return(0); 2074*95c635efSGarrett D'Amore else if (MDOC_BLOCK != n->type) 2075*95c635efSGarrett D'Amore return(1); 2076*95c635efSGarrett D'Amore 2077*95c635efSGarrett D'Amore if (FONT_Em == n->norm->Bf.font) 2078*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 2079*95c635efSGarrett D'Amore else if (FONT_Sy == n->norm->Bf.font) 2080*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 2081*95c635efSGarrett D'Amore else 2082*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE); 2083*95c635efSGarrett D'Amore 2084*95c635efSGarrett D'Amore return(1); 2085*95c635efSGarrett D'Amore } 2086*95c635efSGarrett D'Amore 2087*95c635efSGarrett D'Amore 2088*95c635efSGarrett D'Amore /* ARGSUSED */ 2089*95c635efSGarrett D'Amore static int 2090*95c635efSGarrett D'Amore termp_sm_pre(DECL_ARGS) 2091*95c635efSGarrett D'Amore { 2092*95c635efSGarrett D'Amore 2093*95c635efSGarrett D'Amore assert(n->child && MDOC_TEXT == n->child->type); 2094*95c635efSGarrett D'Amore if (0 == strcmp("on", n->child->string)) { 2095*95c635efSGarrett D'Amore if (p->col) 2096*95c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE; 2097*95c635efSGarrett D'Amore p->flags &= ~TERMP_NONOSPACE; 2098*95c635efSGarrett D'Amore } else 2099*95c635efSGarrett D'Amore p->flags |= TERMP_NONOSPACE; 2100*95c635efSGarrett D'Amore 2101*95c635efSGarrett D'Amore return(0); 2102*95c635efSGarrett D'Amore } 2103*95c635efSGarrett D'Amore 2104*95c635efSGarrett D'Amore 2105*95c635efSGarrett D'Amore /* ARGSUSED */ 2106*95c635efSGarrett D'Amore static int 2107*95c635efSGarrett D'Amore termp_ap_pre(DECL_ARGS) 2108*95c635efSGarrett D'Amore { 2109*95c635efSGarrett D'Amore 2110*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2111*95c635efSGarrett D'Amore term_word(p, "'"); 2112*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2113*95c635efSGarrett D'Amore return(1); 2114*95c635efSGarrett D'Amore } 2115*95c635efSGarrett D'Amore 2116*95c635efSGarrett D'Amore 2117*95c635efSGarrett D'Amore /* ARGSUSED */ 2118*95c635efSGarrett D'Amore static void 2119*95c635efSGarrett D'Amore termp____post(DECL_ARGS) 2120*95c635efSGarrett D'Amore { 2121*95c635efSGarrett D'Amore 2122*95c635efSGarrett D'Amore /* 2123*95c635efSGarrett D'Amore * Handle lists of authors. In general, print each followed by 2124*95c635efSGarrett D'Amore * a comma. Don't print the comma if there are only two 2125*95c635efSGarrett D'Amore * authors. 2126*95c635efSGarrett D'Amore */ 2127*95c635efSGarrett D'Amore if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok) 2128*95c635efSGarrett D'Amore if (NULL == n->next->next || MDOC__A != n->next->next->tok) 2129*95c635efSGarrett D'Amore if (NULL == n->prev || MDOC__A != n->prev->tok) 2130*95c635efSGarrett D'Amore return; 2131*95c635efSGarrett D'Amore 2132*95c635efSGarrett D'Amore /* TODO: %U. */ 2133*95c635efSGarrett D'Amore 2134*95c635efSGarrett D'Amore if (NULL == n->parent || MDOC_Rs != n->parent->tok) 2135*95c635efSGarrett D'Amore return; 2136*95c635efSGarrett D'Amore 2137*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2138*95c635efSGarrett D'Amore if (NULL == n->next) { 2139*95c635efSGarrett D'Amore term_word(p, "."); 2140*95c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 2141*95c635efSGarrett D'Amore } else 2142*95c635efSGarrett D'Amore term_word(p, ","); 2143*95c635efSGarrett D'Amore } 2144*95c635efSGarrett D'Amore 2145*95c635efSGarrett D'Amore 2146*95c635efSGarrett D'Amore /* ARGSUSED */ 2147*95c635efSGarrett D'Amore static int 2148*95c635efSGarrett D'Amore termp_li_pre(DECL_ARGS) 2149*95c635efSGarrett D'Amore { 2150*95c635efSGarrett D'Amore 2151*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE); 2152*95c635efSGarrett D'Amore return(1); 2153*95c635efSGarrett D'Amore } 2154*95c635efSGarrett D'Amore 2155*95c635efSGarrett D'Amore 2156*95c635efSGarrett D'Amore /* ARGSUSED */ 2157*95c635efSGarrett D'Amore static int 2158*95c635efSGarrett D'Amore termp_lk_pre(DECL_ARGS) 2159*95c635efSGarrett D'Amore { 2160*95c635efSGarrett D'Amore const struct mdoc_node *nn, *sv; 2161*95c635efSGarrett D'Amore 2162*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 2163*95c635efSGarrett D'Amore 2164*95c635efSGarrett D'Amore nn = sv = n->child; 2165*95c635efSGarrett D'Amore 2166*95c635efSGarrett D'Amore if (NULL == nn || NULL == nn->next) 2167*95c635efSGarrett D'Amore return(1); 2168*95c635efSGarrett D'Amore 2169*95c635efSGarrett D'Amore for (nn = nn->next; nn; nn = nn->next) 2170*95c635efSGarrett D'Amore term_word(p, nn->string); 2171*95c635efSGarrett D'Amore 2172*95c635efSGarrett D'Amore term_fontpop(p); 2173*95c635efSGarrett D'Amore 2174*95c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2175*95c635efSGarrett D'Amore term_word(p, ":"); 2176*95c635efSGarrett D'Amore 2177*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 2178*95c635efSGarrett D'Amore term_word(p, sv->string); 2179*95c635efSGarrett D'Amore term_fontpop(p); 2180*95c635efSGarrett D'Amore 2181*95c635efSGarrett D'Amore return(0); 2182*95c635efSGarrett D'Amore } 2183*95c635efSGarrett D'Amore 2184*95c635efSGarrett D'Amore 2185*95c635efSGarrett D'Amore /* ARGSUSED */ 2186*95c635efSGarrett D'Amore static int 2187*95c635efSGarrett D'Amore termp_bk_pre(DECL_ARGS) 2188*95c635efSGarrett D'Amore { 2189*95c635efSGarrett D'Amore 2190*95c635efSGarrett D'Amore switch (n->type) { 2191*95c635efSGarrett D'Amore case (MDOC_BLOCK): 2192*95c635efSGarrett D'Amore break; 2193*95c635efSGarrett D'Amore case (MDOC_HEAD): 2194*95c635efSGarrett D'Amore return(0); 2195*95c635efSGarrett D'Amore case (MDOC_BODY): 2196*95c635efSGarrett D'Amore if (n->parent->args || 0 == n->prev->nchild) 2197*95c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP; 2198*95c635efSGarrett D'Amore break; 2199*95c635efSGarrett D'Amore default: 2200*95c635efSGarrett D'Amore abort(); 2201*95c635efSGarrett D'Amore /* NOTREACHED */ 2202*95c635efSGarrett D'Amore } 2203*95c635efSGarrett D'Amore 2204*95c635efSGarrett D'Amore return(1); 2205*95c635efSGarrett D'Amore } 2206*95c635efSGarrett D'Amore 2207*95c635efSGarrett D'Amore 2208*95c635efSGarrett D'Amore /* ARGSUSED */ 2209*95c635efSGarrett D'Amore static void 2210*95c635efSGarrett D'Amore termp_bk_post(DECL_ARGS) 2211*95c635efSGarrett D'Amore { 2212*95c635efSGarrett D'Amore 2213*95c635efSGarrett D'Amore if (MDOC_BODY == n->type) 2214*95c635efSGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); 2215*95c635efSGarrett D'Amore } 2216*95c635efSGarrett D'Amore 2217*95c635efSGarrett D'Amore /* ARGSUSED */ 2218*95c635efSGarrett D'Amore static void 2219*95c635efSGarrett D'Amore termp__t_post(DECL_ARGS) 2220*95c635efSGarrett D'Amore { 2221*95c635efSGarrett D'Amore 2222*95c635efSGarrett D'Amore /* 2223*95c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote 2224*95c635efSGarrett D'Amore * us instead of underlining us (for disambiguation). 2225*95c635efSGarrett D'Amore */ 2226*95c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok && 2227*95c635efSGarrett D'Amore n->parent->norm->Rs.quote_T) 2228*95c635efSGarrett D'Amore termp_quote_post(p, pair, m, n); 2229*95c635efSGarrett D'Amore 2230*95c635efSGarrett D'Amore termp____post(p, pair, m, n); 2231*95c635efSGarrett D'Amore } 2232*95c635efSGarrett D'Amore 2233*95c635efSGarrett D'Amore /* ARGSUSED */ 2234*95c635efSGarrett D'Amore static int 2235*95c635efSGarrett D'Amore termp__t_pre(DECL_ARGS) 2236*95c635efSGarrett D'Amore { 2237*95c635efSGarrett D'Amore 2238*95c635efSGarrett D'Amore /* 2239*95c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote 2240*95c635efSGarrett D'Amore * us instead of underlining us (for disambiguation). 2241*95c635efSGarrett D'Amore */ 2242*95c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok && 2243*95c635efSGarrett D'Amore n->parent->norm->Rs.quote_T) 2244*95c635efSGarrett D'Amore return(termp_quote_pre(p, pair, m, n)); 2245*95c635efSGarrett D'Amore 2246*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 2247*95c635efSGarrett D'Amore return(1); 2248*95c635efSGarrett D'Amore } 2249*95c635efSGarrett D'Amore 2250*95c635efSGarrett D'Amore /* ARGSUSED */ 2251*95c635efSGarrett D'Amore static int 2252*95c635efSGarrett D'Amore termp_under_pre(DECL_ARGS) 2253*95c635efSGarrett D'Amore { 2254*95c635efSGarrett D'Amore 2255*95c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 2256*95c635efSGarrett D'Amore return(1); 2257*95c635efSGarrett D'Amore } 2258