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