1*698f87a4SGarrett D'Amore /* $Id: mdoc_term.c,v 1.258 2013/12/25 21:24:12 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 395c635efSGarrett D'Amore * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*698f87a4SGarrett D'Amore * Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org> 5*698f87a4SGarrett D'Amore * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> 695c635efSGarrett D'Amore * 795c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 895c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 995c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 1095c635efSGarrett D'Amore * 1195c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1295c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1395c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1495c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1595c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1695c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1795c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1895c635efSGarrett D'Amore */ 1995c635efSGarrett D'Amore #ifdef HAVE_CONFIG_H 2095c635efSGarrett D'Amore #include "config.h" 2195c635efSGarrett D'Amore #endif 2295c635efSGarrett D'Amore 2395c635efSGarrett D'Amore #include <sys/types.h> 2495c635efSGarrett D'Amore 2595c635efSGarrett D'Amore #include <assert.h> 2695c635efSGarrett D'Amore #include <ctype.h> 2795c635efSGarrett D'Amore #include <stdint.h> 2895c635efSGarrett D'Amore #include <stdio.h> 2995c635efSGarrett D'Amore #include <stdlib.h> 3095c635efSGarrett D'Amore #include <string.h> 3195c635efSGarrett D'Amore 3295c635efSGarrett D'Amore #include "mandoc.h" 3395c635efSGarrett D'Amore #include "out.h" 3495c635efSGarrett D'Amore #include "term.h" 3595c635efSGarrett D'Amore #include "mdoc.h" 3695c635efSGarrett D'Amore #include "main.h" 3795c635efSGarrett D'Amore 3895c635efSGarrett D'Amore struct termpair { 3995c635efSGarrett D'Amore struct termpair *ppair; 4095c635efSGarrett D'Amore int count; 4195c635efSGarrett D'Amore }; 4295c635efSGarrett D'Amore 4395c635efSGarrett D'Amore #define DECL_ARGS struct termp *p, \ 4495c635efSGarrett D'Amore struct termpair *pair, \ 45*698f87a4SGarrett D'Amore const struct mdoc_meta *meta, \ 46*698f87a4SGarrett D'Amore struct mdoc_node *n 4795c635efSGarrett D'Amore 4895c635efSGarrett D'Amore struct termact { 4995c635efSGarrett D'Amore int (*pre)(DECL_ARGS); 5095c635efSGarrett D'Amore void (*post)(DECL_ARGS); 5195c635efSGarrett D'Amore }; 5295c635efSGarrett D'Amore 5395c635efSGarrett D'Amore static size_t a2width(const struct termp *, const char *); 5495c635efSGarrett D'Amore static size_t a2height(const struct termp *, const char *); 5595c635efSGarrett D'Amore static size_t a2offs(const struct termp *, const char *); 5695c635efSGarrett D'Amore 5795c635efSGarrett D'Amore static void print_bvspace(struct termp *, 5895c635efSGarrett D'Amore const struct mdoc_node *, 5995c635efSGarrett D'Amore const struct mdoc_node *); 6095c635efSGarrett D'Amore static void print_mdoc_node(DECL_ARGS); 6195c635efSGarrett D'Amore static void print_mdoc_nodelist(DECL_ARGS); 6295c635efSGarrett D'Amore static void print_mdoc_head(struct termp *, const void *); 6395c635efSGarrett D'Amore static void print_mdoc_foot(struct termp *, const void *); 6495c635efSGarrett D'Amore static void synopsis_pre(struct termp *, 6595c635efSGarrett D'Amore const struct mdoc_node *); 6695c635efSGarrett D'Amore 6795c635efSGarrett D'Amore static void termp____post(DECL_ARGS); 6895c635efSGarrett D'Amore static void termp__t_post(DECL_ARGS); 6995c635efSGarrett D'Amore static void termp_an_post(DECL_ARGS); 7095c635efSGarrett D'Amore static void termp_bd_post(DECL_ARGS); 7195c635efSGarrett D'Amore static void termp_bk_post(DECL_ARGS); 7295c635efSGarrett D'Amore static void termp_bl_post(DECL_ARGS); 73*698f87a4SGarrett D'Amore static void termp_fd_post(DECL_ARGS); 7495c635efSGarrett D'Amore static void termp_fo_post(DECL_ARGS); 7595c635efSGarrett D'Amore static void termp_in_post(DECL_ARGS); 7695c635efSGarrett D'Amore static void termp_it_post(DECL_ARGS); 7795c635efSGarrett D'Amore static void termp_lb_post(DECL_ARGS); 7895c635efSGarrett D'Amore static void termp_nm_post(DECL_ARGS); 7995c635efSGarrett D'Amore static void termp_pf_post(DECL_ARGS); 8095c635efSGarrett D'Amore static void termp_quote_post(DECL_ARGS); 8195c635efSGarrett D'Amore static void termp_sh_post(DECL_ARGS); 8295c635efSGarrett D'Amore static void termp_ss_post(DECL_ARGS); 8395c635efSGarrett D'Amore 8495c635efSGarrett D'Amore static int termp__a_pre(DECL_ARGS); 8595c635efSGarrett D'Amore static int termp__t_pre(DECL_ARGS); 8695c635efSGarrett D'Amore static int termp_an_pre(DECL_ARGS); 8795c635efSGarrett D'Amore static int termp_ap_pre(DECL_ARGS); 8895c635efSGarrett D'Amore static int termp_bd_pre(DECL_ARGS); 8995c635efSGarrett D'Amore static int termp_bf_pre(DECL_ARGS); 9095c635efSGarrett D'Amore static int termp_bk_pre(DECL_ARGS); 9195c635efSGarrett D'Amore static int termp_bl_pre(DECL_ARGS); 9295c635efSGarrett D'Amore static int termp_bold_pre(DECL_ARGS); 9395c635efSGarrett D'Amore static int termp_bt_pre(DECL_ARGS); 9495c635efSGarrett D'Amore static int termp_bx_pre(DECL_ARGS); 9595c635efSGarrett D'Amore static int termp_cd_pre(DECL_ARGS); 9695c635efSGarrett D'Amore static int termp_d1_pre(DECL_ARGS); 9795c635efSGarrett D'Amore static int termp_ex_pre(DECL_ARGS); 9895c635efSGarrett D'Amore static int termp_fa_pre(DECL_ARGS); 9995c635efSGarrett D'Amore static int termp_fd_pre(DECL_ARGS); 10095c635efSGarrett D'Amore static int termp_fl_pre(DECL_ARGS); 10195c635efSGarrett D'Amore static int termp_fn_pre(DECL_ARGS); 10295c635efSGarrett D'Amore static int termp_fo_pre(DECL_ARGS); 10395c635efSGarrett D'Amore static int termp_ft_pre(DECL_ARGS); 10495c635efSGarrett D'Amore static int termp_in_pre(DECL_ARGS); 10595c635efSGarrett D'Amore static int termp_it_pre(DECL_ARGS); 10695c635efSGarrett D'Amore static int termp_li_pre(DECL_ARGS); 10795c635efSGarrett D'Amore static int termp_lk_pre(DECL_ARGS); 10895c635efSGarrett D'Amore static int termp_nd_pre(DECL_ARGS); 10995c635efSGarrett D'Amore static int termp_nm_pre(DECL_ARGS); 11095c635efSGarrett D'Amore static int termp_ns_pre(DECL_ARGS); 11195c635efSGarrett D'Amore static int termp_quote_pre(DECL_ARGS); 11295c635efSGarrett D'Amore static int termp_rs_pre(DECL_ARGS); 11395c635efSGarrett D'Amore static int termp_rv_pre(DECL_ARGS); 11495c635efSGarrett D'Amore static int termp_sh_pre(DECL_ARGS); 11595c635efSGarrett D'Amore static int termp_sm_pre(DECL_ARGS); 11695c635efSGarrett D'Amore static int termp_sp_pre(DECL_ARGS); 11795c635efSGarrett D'Amore static int termp_ss_pre(DECL_ARGS); 11895c635efSGarrett D'Amore static int termp_under_pre(DECL_ARGS); 11995c635efSGarrett D'Amore static int termp_ud_pre(DECL_ARGS); 12095c635efSGarrett D'Amore static int termp_vt_pre(DECL_ARGS); 12195c635efSGarrett D'Amore static int termp_xr_pre(DECL_ARGS); 12295c635efSGarrett D'Amore static int termp_xx_pre(DECL_ARGS); 12395c635efSGarrett D'Amore 12495c635efSGarrett D'Amore static const struct termact termacts[MDOC_MAX] = { 12595c635efSGarrett D'Amore { termp_ap_pre, NULL }, /* Ap */ 12695c635efSGarrett D'Amore { NULL, NULL }, /* Dd */ 12795c635efSGarrett D'Amore { NULL, NULL }, /* Dt */ 12895c635efSGarrett D'Amore { NULL, NULL }, /* Os */ 12995c635efSGarrett D'Amore { termp_sh_pre, termp_sh_post }, /* Sh */ 13095c635efSGarrett D'Amore { termp_ss_pre, termp_ss_post }, /* Ss */ 13195c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Pp */ 132*698f87a4SGarrett D'Amore { termp_d1_pre, termp_bl_post }, /* D1 */ 133*698f87a4SGarrett D'Amore { termp_d1_pre, termp_bl_post }, /* Dl */ 13495c635efSGarrett D'Amore { termp_bd_pre, termp_bd_post }, /* Bd */ 13595c635efSGarrett D'Amore { NULL, NULL }, /* Ed */ 13695c635efSGarrett D'Amore { termp_bl_pre, termp_bl_post }, /* Bl */ 13795c635efSGarrett D'Amore { NULL, NULL }, /* El */ 13895c635efSGarrett D'Amore { termp_it_pre, termp_it_post }, /* It */ 13995c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ad */ 14095c635efSGarrett D'Amore { termp_an_pre, termp_an_post }, /* An */ 14195c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Ar */ 14295c635efSGarrett D'Amore { termp_cd_pre, NULL }, /* Cd */ 14395c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Cm */ 14495c635efSGarrett D'Amore { NULL, NULL }, /* Dv */ 14595c635efSGarrett D'Amore { NULL, NULL }, /* Er */ 14695c635efSGarrett D'Amore { NULL, NULL }, /* Ev */ 14795c635efSGarrett D'Amore { termp_ex_pre, NULL }, /* Ex */ 14895c635efSGarrett D'Amore { termp_fa_pre, NULL }, /* Fa */ 149*698f87a4SGarrett D'Amore { termp_fd_pre, termp_fd_post }, /* Fd */ 15095c635efSGarrett D'Amore { termp_fl_pre, NULL }, /* Fl */ 15195c635efSGarrett D'Amore { termp_fn_pre, NULL }, /* Fn */ 15295c635efSGarrett D'Amore { termp_ft_pre, NULL }, /* Ft */ 15395c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ic */ 15495c635efSGarrett D'Amore { termp_in_pre, termp_in_post }, /* In */ 15595c635efSGarrett D'Amore { termp_li_pre, NULL }, /* Li */ 15695c635efSGarrett D'Amore { termp_nd_pre, NULL }, /* Nd */ 15795c635efSGarrett D'Amore { termp_nm_pre, termp_nm_post }, /* Nm */ 15895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Op */ 15995c635efSGarrett D'Amore { NULL, NULL }, /* Ot */ 16095c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Pa */ 16195c635efSGarrett D'Amore { termp_rv_pre, NULL }, /* Rv */ 16295c635efSGarrett D'Amore { NULL, NULL }, /* St */ 16395c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Va */ 16495c635efSGarrett D'Amore { termp_vt_pre, NULL }, /* Vt */ 16595c635efSGarrett D'Amore { termp_xr_pre, NULL }, /* Xr */ 16695c635efSGarrett D'Amore { termp__a_pre, termp____post }, /* %A */ 16795c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %B */ 16895c635efSGarrett D'Amore { NULL, termp____post }, /* %D */ 16995c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %I */ 17095c635efSGarrett D'Amore { termp_under_pre, termp____post }, /* %J */ 17195c635efSGarrett D'Amore { NULL, termp____post }, /* %N */ 17295c635efSGarrett D'Amore { NULL, termp____post }, /* %O */ 17395c635efSGarrett D'Amore { NULL, termp____post }, /* %P */ 17495c635efSGarrett D'Amore { NULL, termp____post }, /* %R */ 17595c635efSGarrett D'Amore { termp__t_pre, termp__t_post }, /* %T */ 17695c635efSGarrett D'Amore { NULL, termp____post }, /* %V */ 17795c635efSGarrett D'Amore { NULL, NULL }, /* Ac */ 17895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ao */ 17995c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Aq */ 18095c635efSGarrett D'Amore { NULL, NULL }, /* At */ 18195c635efSGarrett D'Amore { NULL, NULL }, /* Bc */ 18295c635efSGarrett D'Amore { termp_bf_pre, NULL }, /* Bf */ 18395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bo */ 18495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bq */ 18595c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Bsx */ 18695c635efSGarrett D'Amore { termp_bx_pre, NULL }, /* Bx */ 18795c635efSGarrett D'Amore { NULL, NULL }, /* Db */ 18895c635efSGarrett D'Amore { NULL, NULL }, /* Dc */ 18995c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Do */ 19095c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Dq */ 19195c635efSGarrett D'Amore { NULL, NULL }, /* Ec */ /* FIXME: no space */ 19295c635efSGarrett D'Amore { NULL, NULL }, /* Ef */ 19395c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Em */ 19495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Eo */ 19595c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Fx */ 19695c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Ms */ 197*698f87a4SGarrett D'Amore { NULL, NULL }, /* No */ 19895c635efSGarrett D'Amore { termp_ns_pre, NULL }, /* Ns */ 19995c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Nx */ 20095c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ox */ 20195c635efSGarrett D'Amore { NULL, NULL }, /* Pc */ 202*698f87a4SGarrett D'Amore { NULL, termp_pf_post }, /* Pf */ 20395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Po */ 20495c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Pq */ 20595c635efSGarrett D'Amore { NULL, NULL }, /* Qc */ 20695c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Ql */ 20795c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qo */ 20895c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Qq */ 20995c635efSGarrett D'Amore { NULL, NULL }, /* Re */ 21095c635efSGarrett D'Amore { termp_rs_pre, NULL }, /* Rs */ 21195c635efSGarrett D'Amore { NULL, NULL }, /* Sc */ 21295c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* So */ 21395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Sq */ 21495c635efSGarrett D'Amore { termp_sm_pre, NULL }, /* Sm */ 21595c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Sx */ 21695c635efSGarrett D'Amore { termp_bold_pre, NULL }, /* Sy */ 21795c635efSGarrett D'Amore { NULL, NULL }, /* Tn */ 21895c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Ux */ 21995c635efSGarrett D'Amore { NULL, NULL }, /* Xc */ 22095c635efSGarrett D'Amore { NULL, NULL }, /* Xo */ 22195c635efSGarrett D'Amore { termp_fo_pre, termp_fo_post }, /* Fo */ 22295c635efSGarrett D'Amore { NULL, NULL }, /* Fc */ 22395c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Oo */ 22495c635efSGarrett D'Amore { NULL, NULL }, /* Oc */ 22595c635efSGarrett D'Amore { termp_bk_pre, termp_bk_post }, /* Bk */ 22695c635efSGarrett D'Amore { NULL, NULL }, /* Ek */ 22795c635efSGarrett D'Amore { termp_bt_pre, NULL }, /* Bt */ 22895c635efSGarrett D'Amore { NULL, NULL }, /* Hf */ 22995c635efSGarrett D'Amore { NULL, NULL }, /* Fr */ 23095c635efSGarrett D'Amore { termp_ud_pre, NULL }, /* Ud */ 23195c635efSGarrett D'Amore { NULL, termp_lb_post }, /* Lb */ 23295c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* Lp */ 23395c635efSGarrett D'Amore { termp_lk_pre, NULL }, /* Lk */ 23495c635efSGarrett D'Amore { termp_under_pre, NULL }, /* Mt */ 23595c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Brq */ 23695c635efSGarrett D'Amore { termp_quote_pre, termp_quote_post }, /* Bro */ 23795c635efSGarrett D'Amore { NULL, NULL }, /* Brc */ 23895c635efSGarrett D'Amore { NULL, termp____post }, /* %C */ 23995c635efSGarrett D'Amore { NULL, NULL }, /* Es */ /* TODO */ 24095c635efSGarrett D'Amore { NULL, NULL }, /* En */ /* TODO */ 24195c635efSGarrett D'Amore { termp_xx_pre, NULL }, /* Dx */ 24295c635efSGarrett D'Amore { NULL, termp____post }, /* %Q */ 24395c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* br */ 24495c635efSGarrett D'Amore { termp_sp_pre, NULL }, /* sp */ 245*698f87a4SGarrett D'Amore { NULL, termp____post }, /* %U */ 24695c635efSGarrett D'Amore { NULL, NULL }, /* Ta */ 24795c635efSGarrett D'Amore }; 24895c635efSGarrett D'Amore 24995c635efSGarrett D'Amore 25095c635efSGarrett D'Amore void 25195c635efSGarrett D'Amore terminal_mdoc(void *arg, const struct mdoc *mdoc) 25295c635efSGarrett D'Amore { 25395c635efSGarrett D'Amore const struct mdoc_node *n; 254*698f87a4SGarrett D'Amore const struct mdoc_meta *meta; 25595c635efSGarrett D'Amore struct termp *p; 25695c635efSGarrett D'Amore 25795c635efSGarrett D'Amore p = (struct termp *)arg; 25895c635efSGarrett D'Amore 25995c635efSGarrett D'Amore if (0 == p->defindent) 26095c635efSGarrett D'Amore p->defindent = 5; 26195c635efSGarrett D'Amore 26295c635efSGarrett D'Amore p->overstep = 0; 26395c635efSGarrett D'Amore p->maxrmargin = p->defrmargin; 26495c635efSGarrett D'Amore p->tabwidth = term_len(p, 5); 26595c635efSGarrett D'Amore 26695c635efSGarrett D'Amore if (NULL == p->symtab) 26795c635efSGarrett D'Amore p->symtab = mchars_alloc(); 26895c635efSGarrett D'Amore 26995c635efSGarrett D'Amore n = mdoc_node(mdoc); 270*698f87a4SGarrett D'Amore meta = mdoc_meta(mdoc); 27195c635efSGarrett D'Amore 272*698f87a4SGarrett D'Amore term_begin(p, print_mdoc_head, print_mdoc_foot, meta); 27395c635efSGarrett D'Amore 27495c635efSGarrett D'Amore if (n->child) 275*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, NULL, meta, n->child); 27695c635efSGarrett D'Amore 27795c635efSGarrett D'Amore term_end(p); 27895c635efSGarrett D'Amore } 27995c635efSGarrett D'Amore 28095c635efSGarrett D'Amore 28195c635efSGarrett D'Amore static void 28295c635efSGarrett D'Amore print_mdoc_nodelist(DECL_ARGS) 28395c635efSGarrett D'Amore { 28495c635efSGarrett D'Amore 285*698f87a4SGarrett D'Amore print_mdoc_node(p, pair, meta, n); 28695c635efSGarrett D'Amore if (n->next) 287*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, pair, meta, n->next); 28895c635efSGarrett D'Amore } 28995c635efSGarrett D'Amore 29095c635efSGarrett D'Amore 29195c635efSGarrett D'Amore /* ARGSUSED */ 29295c635efSGarrett D'Amore static void 29395c635efSGarrett D'Amore print_mdoc_node(DECL_ARGS) 29495c635efSGarrett D'Amore { 29595c635efSGarrett D'Amore int chld; 29695c635efSGarrett D'Amore struct termpair npair; 29795c635efSGarrett D'Amore size_t offset, rmargin; 29895c635efSGarrett D'Amore 29995c635efSGarrett D'Amore chld = 1; 30095c635efSGarrett D'Amore offset = p->offset; 30195c635efSGarrett D'Amore rmargin = p->rmargin; 302*698f87a4SGarrett D'Amore n->prev_font = term_fontq(p); 30395c635efSGarrett D'Amore 30495c635efSGarrett D'Amore memset(&npair, 0, sizeof(struct termpair)); 30595c635efSGarrett D'Amore npair.ppair = pair; 30695c635efSGarrett D'Amore 30795c635efSGarrett D'Amore /* 30895c635efSGarrett D'Amore * Keeps only work until the end of a line. If a keep was 30995c635efSGarrett D'Amore * invoked in a prior line, revert it to PREKEEP. 31095c635efSGarrett D'Amore */ 31195c635efSGarrett D'Amore 312*698f87a4SGarrett D'Amore if (TERMP_KEEP & p->flags) { 313*698f87a4SGarrett D'Amore if (n->prev ? (n->prev->lastline != n->line) : 314*698f87a4SGarrett D'Amore (n->parent && n->parent->line != n->line)) { 31595c635efSGarrett D'Amore p->flags &= ~TERMP_KEEP; 31695c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP; 31795c635efSGarrett D'Amore } 31895c635efSGarrett D'Amore } 31995c635efSGarrett D'Amore 32095c635efSGarrett D'Amore /* 32195c635efSGarrett D'Amore * After the keep flags have been set up, we may now 32295c635efSGarrett D'Amore * produce output. Note that some pre-handlers do so. 32395c635efSGarrett D'Amore */ 32495c635efSGarrett D'Amore 32595c635efSGarrett D'Amore switch (n->type) { 32695c635efSGarrett D'Amore case (MDOC_TEXT): 32795c635efSGarrett D'Amore if (' ' == *n->string && MDOC_LINE & n->flags) 32895c635efSGarrett D'Amore term_newln(p); 32995c635efSGarrett D'Amore if (MDOC_DELIMC & n->flags) 33095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 33195c635efSGarrett D'Amore term_word(p, n->string); 33295c635efSGarrett D'Amore if (MDOC_DELIMO & n->flags) 33395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 33495c635efSGarrett D'Amore break; 33595c635efSGarrett D'Amore case (MDOC_EQN): 33695c635efSGarrett D'Amore term_eqn(p, n->eqn); 33795c635efSGarrett D'Amore break; 33895c635efSGarrett D'Amore case (MDOC_TBL): 33995c635efSGarrett D'Amore term_tbl(p, n->span); 34095c635efSGarrett D'Amore break; 34195c635efSGarrett D'Amore default: 34295c635efSGarrett D'Amore if (termacts[n->tok].pre && ENDBODY_NOT == n->end) 34395c635efSGarrett D'Amore chld = (*termacts[n->tok].pre) 344*698f87a4SGarrett D'Amore (p, &npair, meta, n); 34595c635efSGarrett D'Amore break; 34695c635efSGarrett D'Amore } 34795c635efSGarrett D'Amore 34895c635efSGarrett D'Amore if (chld && n->child) 349*698f87a4SGarrett D'Amore print_mdoc_nodelist(p, &npair, meta, n->child); 35095c635efSGarrett D'Amore 351*698f87a4SGarrett D'Amore term_fontpopq(p, 352*698f87a4SGarrett D'Amore (ENDBODY_NOT == n->end ? n : n->pending)->prev_font); 35395c635efSGarrett D'Amore 35495c635efSGarrett D'Amore switch (n->type) { 35595c635efSGarrett D'Amore case (MDOC_TEXT): 35695c635efSGarrett D'Amore break; 35795c635efSGarrett D'Amore case (MDOC_TBL): 35895c635efSGarrett D'Amore break; 35995c635efSGarrett D'Amore case (MDOC_EQN): 36095c635efSGarrett D'Amore break; 36195c635efSGarrett D'Amore default: 36295c635efSGarrett D'Amore if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags) 36395c635efSGarrett D'Amore break; 364*698f87a4SGarrett D'Amore (void)(*termacts[n->tok].post)(p, &npair, meta, n); 36595c635efSGarrett D'Amore 36695c635efSGarrett D'Amore /* 36795c635efSGarrett D'Amore * Explicit end tokens not only call the post 36895c635efSGarrett D'Amore * handler, but also tell the respective block 36995c635efSGarrett D'Amore * that it must not call the post handler again. 37095c635efSGarrett D'Amore */ 37195c635efSGarrett D'Amore if (ENDBODY_NOT != n->end) 37295c635efSGarrett D'Amore n->pending->flags |= MDOC_ENDED; 37395c635efSGarrett D'Amore 37495c635efSGarrett D'Amore /* 37595c635efSGarrett D'Amore * End of line terminating an implicit block 37695c635efSGarrett D'Amore * while an explicit block is still open. 37795c635efSGarrett D'Amore * Continue the explicit block without spacing. 37895c635efSGarrett D'Amore */ 37995c635efSGarrett D'Amore if (ENDBODY_NOSPACE == n->end) 38095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 38195c635efSGarrett D'Amore break; 38295c635efSGarrett D'Amore } 38395c635efSGarrett D'Amore 38495c635efSGarrett D'Amore if (MDOC_EOS & n->flags) 38595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 38695c635efSGarrett D'Amore 38795c635efSGarrett D'Amore p->offset = offset; 38895c635efSGarrett D'Amore p->rmargin = rmargin; 38995c635efSGarrett D'Amore } 39095c635efSGarrett D'Amore 39195c635efSGarrett D'Amore 39295c635efSGarrett D'Amore static void 39395c635efSGarrett D'Amore print_mdoc_foot(struct termp *p, const void *arg) 39495c635efSGarrett D'Amore { 395*698f87a4SGarrett D'Amore const struct mdoc_meta *meta; 39695c635efSGarrett D'Amore 397*698f87a4SGarrett D'Amore meta = (const struct mdoc_meta *)arg; 39895c635efSGarrett D'Amore 39995c635efSGarrett D'Amore term_fontrepl(p, TERMFONT_NONE); 40095c635efSGarrett D'Amore 40195c635efSGarrett D'Amore /* 40295c635efSGarrett D'Amore * Output the footer in new-groff style, that is, three columns 40395c635efSGarrett D'Amore * with the middle being the manual date and flanking columns 40495c635efSGarrett D'Amore * being the operating system: 40595c635efSGarrett D'Amore * 40695c635efSGarrett D'Amore * SYSTEM DATE SYSTEM 40795c635efSGarrett D'Amore */ 40895c635efSGarrett D'Amore 40995c635efSGarrett D'Amore term_vspace(p); 41095c635efSGarrett D'Amore 41195c635efSGarrett D'Amore p->offset = 0; 41295c635efSGarrett D'Amore p->rmargin = (p->maxrmargin - 413*698f87a4SGarrett D'Amore term_strlen(p, meta->date) + term_len(p, 1)) / 2; 414*698f87a4SGarrett D'Amore p->trailspace = 1; 41595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; 41695c635efSGarrett D'Amore 417*698f87a4SGarrett D'Amore term_word(p, meta->os); 41895c635efSGarrett D'Amore term_flushln(p); 41995c635efSGarrett D'Amore 42095c635efSGarrett D'Amore p->offset = p->rmargin; 421*698f87a4SGarrett D'Amore p->rmargin = p->maxrmargin - term_strlen(p, meta->os); 42295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 42395c635efSGarrett D'Amore 424*698f87a4SGarrett D'Amore term_word(p, meta->date); 42595c635efSGarrett D'Amore term_flushln(p); 42695c635efSGarrett D'Amore 42795c635efSGarrett D'Amore p->offset = p->rmargin; 42895c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 429*698f87a4SGarrett D'Amore p->trailspace = 0; 43095c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 43195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 43295c635efSGarrett D'Amore 433*698f87a4SGarrett D'Amore term_word(p, meta->os); 43495c635efSGarrett D'Amore term_flushln(p); 43595c635efSGarrett D'Amore 43695c635efSGarrett D'Amore p->offset = 0; 43795c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 43895c635efSGarrett D'Amore p->flags = 0; 43995c635efSGarrett D'Amore } 44095c635efSGarrett D'Amore 44195c635efSGarrett D'Amore 44295c635efSGarrett D'Amore static void 44395c635efSGarrett D'Amore print_mdoc_head(struct termp *p, const void *arg) 44495c635efSGarrett D'Amore { 44595c635efSGarrett D'Amore char buf[BUFSIZ], title[BUFSIZ]; 44695c635efSGarrett D'Amore size_t buflen, titlen; 447*698f87a4SGarrett D'Amore const struct mdoc_meta *meta; 44895c635efSGarrett D'Amore 449*698f87a4SGarrett D'Amore meta = (const struct mdoc_meta *)arg; 45095c635efSGarrett D'Amore 45195c635efSGarrett D'Amore /* 45295c635efSGarrett D'Amore * The header is strange. It has three components, which are 45395c635efSGarrett D'Amore * really two with the first duplicated. It goes like this: 45495c635efSGarrett D'Amore * 45595c635efSGarrett D'Amore * IDENTIFIER TITLE IDENTIFIER 45695c635efSGarrett D'Amore * 45795c635efSGarrett D'Amore * The IDENTIFIER is NAME(SECTION), which is the command-name 45895c635efSGarrett D'Amore * (if given, or "unknown" if not) followed by the manual page 45995c635efSGarrett D'Amore * section. These are given in `Dt'. The TITLE is a free-form 46095c635efSGarrett D'Amore * string depending on the manual volume. If not specified, it 46195c635efSGarrett D'Amore * switches on the manual section. 46295c635efSGarrett D'Amore */ 46395c635efSGarrett D'Amore 46495c635efSGarrett D'Amore p->offset = 0; 46595c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 46695c635efSGarrett D'Amore 467*698f87a4SGarrett D'Amore assert(meta->vol); 468*698f87a4SGarrett D'Amore strlcpy(buf, meta->vol, BUFSIZ); 46995c635efSGarrett D'Amore buflen = term_strlen(p, buf); 47095c635efSGarrett D'Amore 471*698f87a4SGarrett D'Amore if (meta->arch) { 47295c635efSGarrett D'Amore strlcat(buf, " (", BUFSIZ); 473*698f87a4SGarrett D'Amore strlcat(buf, meta->arch, BUFSIZ); 47495c635efSGarrett D'Amore strlcat(buf, ")", BUFSIZ); 47595c635efSGarrett D'Amore } 47695c635efSGarrett D'Amore 477*698f87a4SGarrett D'Amore snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec); 47895c635efSGarrett D'Amore titlen = term_strlen(p, title); 47995c635efSGarrett D'Amore 48095c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; 481*698f87a4SGarrett D'Amore p->trailspace = 1; 48295c635efSGarrett D'Amore p->offset = 0; 48395c635efSGarrett D'Amore p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ? 48495c635efSGarrett D'Amore (p->maxrmargin - 48595c635efSGarrett D'Amore term_strlen(p, buf) + term_len(p, 1)) / 2 : 48695c635efSGarrett D'Amore p->maxrmargin - buflen; 48795c635efSGarrett D'Amore 48895c635efSGarrett D'Amore term_word(p, title); 48995c635efSGarrett D'Amore term_flushln(p); 49095c635efSGarrett D'Amore 49195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 49295c635efSGarrett D'Amore p->offset = p->rmargin; 49395c635efSGarrett D'Amore p->rmargin = p->offset + buflen + titlen < p->maxrmargin ? 49495c635efSGarrett D'Amore p->maxrmargin - titlen : p->maxrmargin; 49595c635efSGarrett D'Amore 49695c635efSGarrett D'Amore term_word(p, buf); 49795c635efSGarrett D'Amore term_flushln(p); 49895c635efSGarrett D'Amore 49995c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 500*698f87a4SGarrett D'Amore p->trailspace = 0; 50195c635efSGarrett D'Amore if (p->rmargin + titlen <= p->maxrmargin) { 50295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 50395c635efSGarrett D'Amore p->offset = p->rmargin; 50495c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 50595c635efSGarrett D'Amore term_word(p, title); 50695c635efSGarrett D'Amore term_flushln(p); 50795c635efSGarrett D'Amore } 50895c635efSGarrett D'Amore 50995c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE; 51095c635efSGarrett D'Amore p->offset = 0; 51195c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 51295c635efSGarrett D'Amore } 51395c635efSGarrett D'Amore 51495c635efSGarrett D'Amore 51595c635efSGarrett D'Amore static size_t 51695c635efSGarrett D'Amore a2height(const struct termp *p, const char *v) 51795c635efSGarrett D'Amore { 51895c635efSGarrett D'Amore struct roffsu su; 51995c635efSGarrett D'Amore 52095c635efSGarrett D'Amore 52195c635efSGarrett D'Amore assert(v); 52295c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_VS)) 52395c635efSGarrett D'Amore SCALE_VS_INIT(&su, atoi(v)); 52495c635efSGarrett D'Amore 52595c635efSGarrett D'Amore return(term_vspan(p, &su)); 52695c635efSGarrett D'Amore } 52795c635efSGarrett D'Amore 52895c635efSGarrett D'Amore 52995c635efSGarrett D'Amore static size_t 53095c635efSGarrett D'Amore a2width(const struct termp *p, const char *v) 53195c635efSGarrett D'Amore { 53295c635efSGarrett D'Amore struct roffsu su; 53395c635efSGarrett D'Amore 53495c635efSGarrett D'Amore assert(v); 53595c635efSGarrett D'Amore if ( ! a2roffsu(v, &su, SCALE_MAX)) 53695c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v)); 53795c635efSGarrett D'Amore 53895c635efSGarrett D'Amore return(term_hspan(p, &su)); 53995c635efSGarrett D'Amore } 54095c635efSGarrett D'Amore 54195c635efSGarrett D'Amore 54295c635efSGarrett D'Amore static size_t 54395c635efSGarrett D'Amore a2offs(const struct termp *p, const char *v) 54495c635efSGarrett D'Amore { 54595c635efSGarrett D'Amore struct roffsu su; 54695c635efSGarrett D'Amore 54795c635efSGarrett D'Amore if ('\0' == *v) 54895c635efSGarrett D'Amore return(0); 54995c635efSGarrett D'Amore else if (0 == strcmp(v, "left")) 55095c635efSGarrett D'Amore return(0); 55195c635efSGarrett D'Amore else if (0 == strcmp(v, "indent")) 55295c635efSGarrett D'Amore return(term_len(p, p->defindent + 1)); 55395c635efSGarrett D'Amore else if (0 == strcmp(v, "indent-two")) 55495c635efSGarrett D'Amore return(term_len(p, (p->defindent + 1) * 2)); 55595c635efSGarrett D'Amore else if ( ! a2roffsu(v, &su, SCALE_MAX)) 55695c635efSGarrett D'Amore SCALE_HS_INIT(&su, term_strlen(p, v)); 55795c635efSGarrett D'Amore 55895c635efSGarrett D'Amore return(term_hspan(p, &su)); 55995c635efSGarrett D'Amore } 56095c635efSGarrett D'Amore 56195c635efSGarrett D'Amore 56295c635efSGarrett D'Amore /* 56395c635efSGarrett D'Amore * Determine how much space to print out before block elements of `It' 56495c635efSGarrett D'Amore * (and thus `Bl') and `Bd'. And then go ahead and print that space, 56595c635efSGarrett D'Amore * too. 56695c635efSGarrett D'Amore */ 56795c635efSGarrett D'Amore static void 56895c635efSGarrett D'Amore print_bvspace(struct termp *p, 56995c635efSGarrett D'Amore const struct mdoc_node *bl, 57095c635efSGarrett D'Amore const struct mdoc_node *n) 57195c635efSGarrett D'Amore { 57295c635efSGarrett D'Amore const struct mdoc_node *nn; 57395c635efSGarrett D'Amore 57495c635efSGarrett D'Amore assert(n); 57595c635efSGarrett D'Amore 57695c635efSGarrett D'Amore term_newln(p); 57795c635efSGarrett D'Amore 57895c635efSGarrett D'Amore if (MDOC_Bd == bl->tok && bl->norm->Bd.comp) 57995c635efSGarrett D'Amore return; 58095c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && bl->norm->Bl.comp) 58195c635efSGarrett D'Amore return; 58295c635efSGarrett D'Amore 58395c635efSGarrett D'Amore /* Do not vspace directly after Ss/Sh. */ 58495c635efSGarrett D'Amore 58595c635efSGarrett D'Amore for (nn = n; nn; nn = nn->parent) { 58695c635efSGarrett D'Amore if (MDOC_BLOCK != nn->type) 58795c635efSGarrett D'Amore continue; 58895c635efSGarrett D'Amore if (MDOC_Ss == nn->tok) 58995c635efSGarrett D'Amore return; 59095c635efSGarrett D'Amore if (MDOC_Sh == nn->tok) 59195c635efSGarrett D'Amore return; 59295c635efSGarrett D'Amore if (NULL == nn->prev) 59395c635efSGarrett D'Amore continue; 59495c635efSGarrett D'Amore break; 59595c635efSGarrett D'Amore } 59695c635efSGarrett D'Amore 59795c635efSGarrett D'Amore /* A `-column' does not assert vspace within the list. */ 59895c635efSGarrett D'Amore 59995c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type) 60095c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok) 60195c635efSGarrett D'Amore return; 60295c635efSGarrett D'Amore 60395c635efSGarrett D'Amore /* A `-diag' without body does not vspace. */ 60495c635efSGarrett D'Amore 60595c635efSGarrett D'Amore if (MDOC_Bl == bl->tok && LIST_diag == bl->norm->Bl.type) 60695c635efSGarrett D'Amore if (n->prev && MDOC_It == n->prev->tok) { 60795c635efSGarrett D'Amore assert(n->prev->body); 60895c635efSGarrett D'Amore if (NULL == n->prev->body->child) 60995c635efSGarrett D'Amore return; 61095c635efSGarrett D'Amore } 61195c635efSGarrett D'Amore 61295c635efSGarrett D'Amore term_vspace(p); 61395c635efSGarrett D'Amore } 61495c635efSGarrett D'Amore 61595c635efSGarrett D'Amore 61695c635efSGarrett D'Amore /* ARGSUSED */ 61795c635efSGarrett D'Amore static int 61895c635efSGarrett D'Amore termp_it_pre(DECL_ARGS) 61995c635efSGarrett D'Amore { 62095c635efSGarrett D'Amore const struct mdoc_node *bl, *nn; 62195c635efSGarrett D'Amore char buf[7]; 62295c635efSGarrett D'Amore int i; 62395c635efSGarrett D'Amore size_t width, offset, ncols, dcol; 62495c635efSGarrett D'Amore enum mdoc_list type; 62595c635efSGarrett D'Amore 62695c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 62795c635efSGarrett D'Amore print_bvspace(p, n->parent->parent, n); 62895c635efSGarrett D'Amore return(1); 62995c635efSGarrett D'Amore } 63095c635efSGarrett D'Amore 63195c635efSGarrett D'Amore bl = n->parent->parent->parent; 63295c635efSGarrett D'Amore type = bl->norm->Bl.type; 63395c635efSGarrett D'Amore 63495c635efSGarrett D'Amore /* 63595c635efSGarrett D'Amore * First calculate width and offset. This is pretty easy unless 63695c635efSGarrett D'Amore * we're a -column list, in which case all prior columns must 63795c635efSGarrett D'Amore * be accounted for. 63895c635efSGarrett D'Amore */ 63995c635efSGarrett D'Amore 64095c635efSGarrett D'Amore width = offset = 0; 64195c635efSGarrett D'Amore 64295c635efSGarrett D'Amore if (bl->norm->Bl.offs) 64395c635efSGarrett D'Amore offset = a2offs(p, bl->norm->Bl.offs); 64495c635efSGarrett D'Amore 64595c635efSGarrett D'Amore switch (type) { 64695c635efSGarrett D'Amore case (LIST_column): 64795c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 64895c635efSGarrett D'Amore break; 64995c635efSGarrett D'Amore 65095c635efSGarrett D'Amore /* 65195c635efSGarrett D'Amore * Imitate groff's column handling: 65295c635efSGarrett D'Amore * - For each earlier column, add its width. 65395c635efSGarrett D'Amore * - For less than 5 columns, add four more blanks per 65495c635efSGarrett D'Amore * column. 65595c635efSGarrett D'Amore * - For exactly 5 columns, add three more blank per 65695c635efSGarrett D'Amore * column. 65795c635efSGarrett D'Amore * - For more than 5 columns, add only one column. 65895c635efSGarrett D'Amore */ 65995c635efSGarrett D'Amore ncols = bl->norm->Bl.ncols; 66095c635efSGarrett D'Amore 66195c635efSGarrett D'Amore /* LINTED */ 66295c635efSGarrett D'Amore dcol = ncols < 5 ? term_len(p, 4) : 66395c635efSGarrett D'Amore ncols == 5 ? term_len(p, 3) : term_len(p, 1); 66495c635efSGarrett D'Amore 66595c635efSGarrett D'Amore /* 66695c635efSGarrett D'Amore * Calculate the offset by applying all prior MDOC_BODY, 66795c635efSGarrett D'Amore * so we stop at the MDOC_HEAD (NULL == nn->prev). 66895c635efSGarrett D'Amore */ 66995c635efSGarrett D'Amore 67095c635efSGarrett D'Amore for (i = 0, nn = n->prev; 67195c635efSGarrett D'Amore nn->prev && i < (int)ncols; 67295c635efSGarrett D'Amore nn = nn->prev, i++) 67395c635efSGarrett D'Amore offset += dcol + a2width 67495c635efSGarrett D'Amore (p, bl->norm->Bl.cols[i]); 67595c635efSGarrett D'Amore 67695c635efSGarrett D'Amore /* 67795c635efSGarrett D'Amore * When exceeding the declared number of columns, leave 67895c635efSGarrett D'Amore * the remaining widths at 0. This will later be 67995c635efSGarrett D'Amore * adjusted to the default width of 10, or, for the last 68095c635efSGarrett D'Amore * column, stretched to the right margin. 68195c635efSGarrett D'Amore */ 68295c635efSGarrett D'Amore if (i >= (int)ncols) 68395c635efSGarrett D'Amore break; 68495c635efSGarrett D'Amore 68595c635efSGarrett D'Amore /* 68695c635efSGarrett D'Amore * Use the declared column widths, extended as explained 68795c635efSGarrett D'Amore * in the preceding paragraph. 68895c635efSGarrett D'Amore */ 68995c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.cols[i]) + dcol; 69095c635efSGarrett D'Amore break; 69195c635efSGarrett D'Amore default: 69295c635efSGarrett D'Amore if (NULL == bl->norm->Bl.width) 69395c635efSGarrett D'Amore break; 69495c635efSGarrett D'Amore 69595c635efSGarrett D'Amore /* 69695c635efSGarrett D'Amore * Note: buffer the width by 2, which is groff's magic 69795c635efSGarrett D'Amore * number for buffering single arguments. See the above 69895c635efSGarrett D'Amore * handling for column for how this changes. 69995c635efSGarrett D'Amore */ 70095c635efSGarrett D'Amore assert(bl->norm->Bl.width); 70195c635efSGarrett D'Amore width = a2width(p, bl->norm->Bl.width) + term_len(p, 2); 70295c635efSGarrett D'Amore break; 70395c635efSGarrett D'Amore } 70495c635efSGarrett D'Amore 70595c635efSGarrett D'Amore /* 70695c635efSGarrett D'Amore * List-type can override the width in the case of fixed-head 70795c635efSGarrett D'Amore * values (bullet, dash/hyphen, enum). Tags need a non-zero 70895c635efSGarrett D'Amore * offset. 70995c635efSGarrett D'Amore */ 71095c635efSGarrett D'Amore 71195c635efSGarrett D'Amore switch (type) { 71295c635efSGarrett D'Amore case (LIST_bullet): 71395c635efSGarrett D'Amore /* FALLTHROUGH */ 71495c635efSGarrett D'Amore case (LIST_dash): 71595c635efSGarrett D'Amore /* FALLTHROUGH */ 71695c635efSGarrett D'Amore case (LIST_hyphen): 717*698f87a4SGarrett D'Amore /* FALLTHROUGH */ 71895c635efSGarrett D'Amore case (LIST_enum): 719*698f87a4SGarrett D'Amore if (width < term_len(p, 2)) 720*698f87a4SGarrett D'Amore width = term_len(p, 2); 72195c635efSGarrett D'Amore break; 72295c635efSGarrett D'Amore case (LIST_hang): 72395c635efSGarrett D'Amore if (0 == width) 72495c635efSGarrett D'Amore width = term_len(p, 8); 72595c635efSGarrett D'Amore break; 72695c635efSGarrett D'Amore case (LIST_column): 72795c635efSGarrett D'Amore /* FALLTHROUGH */ 72895c635efSGarrett D'Amore case (LIST_tag): 72995c635efSGarrett D'Amore if (0 == width) 73095c635efSGarrett D'Amore width = term_len(p, 10); 73195c635efSGarrett D'Amore break; 73295c635efSGarrett D'Amore default: 73395c635efSGarrett D'Amore break; 73495c635efSGarrett D'Amore } 73595c635efSGarrett D'Amore 73695c635efSGarrett D'Amore /* 73795c635efSGarrett D'Amore * Whitespace control. Inset bodies need an initial space, 73895c635efSGarrett D'Amore * while diagonal bodies need two. 73995c635efSGarrett D'Amore */ 74095c635efSGarrett D'Amore 74195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 74295c635efSGarrett D'Amore 74395c635efSGarrett D'Amore switch (type) { 74495c635efSGarrett D'Amore case (LIST_diag): 74595c635efSGarrett D'Amore if (MDOC_BODY == n->type) 74695c635efSGarrett D'Amore term_word(p, "\\ \\ "); 74795c635efSGarrett D'Amore break; 74895c635efSGarrett D'Amore case (LIST_inset): 74995c635efSGarrett D'Amore if (MDOC_BODY == n->type) 75095c635efSGarrett D'Amore term_word(p, "\\ "); 75195c635efSGarrett D'Amore break; 75295c635efSGarrett D'Amore default: 75395c635efSGarrett D'Amore break; 75495c635efSGarrett D'Amore } 75595c635efSGarrett D'Amore 75695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 75795c635efSGarrett D'Amore 75895c635efSGarrett D'Amore switch (type) { 75995c635efSGarrett D'Amore case (LIST_diag): 76095c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 76195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 76295c635efSGarrett D'Amore break; 76395c635efSGarrett D'Amore default: 76495c635efSGarrett D'Amore break; 76595c635efSGarrett D'Amore } 76695c635efSGarrett D'Amore 76795c635efSGarrett D'Amore /* 76895c635efSGarrett D'Amore * Pad and break control. This is the tricky part. These flags 76995c635efSGarrett D'Amore * are documented in term_flushln() in term.c. Note that we're 77095c635efSGarrett D'Amore * going to unset all of these flags in termp_it_post() when we 77195c635efSGarrett D'Amore * exit. 77295c635efSGarrett D'Amore */ 77395c635efSGarrett D'Amore 77495c635efSGarrett D'Amore switch (type) { 775*698f87a4SGarrett D'Amore case (LIST_enum): 776*698f87a4SGarrett D'Amore /* 777*698f87a4SGarrett D'Amore * Weird special case. 778*698f87a4SGarrett D'Amore * Very narrow enum lists actually hang. 779*698f87a4SGarrett D'Amore */ 780*698f87a4SGarrett D'Amore if (width == term_len(p, 2)) 781*698f87a4SGarrett D'Amore p->flags |= TERMP_HANG; 782*698f87a4SGarrett D'Amore /* FALLTHROUGH */ 78395c635efSGarrett D'Amore case (LIST_bullet): 78495c635efSGarrett D'Amore /* FALLTHROUGH */ 78595c635efSGarrett D'Amore case (LIST_dash): 78695c635efSGarrett D'Amore /* FALLTHROUGH */ 78795c635efSGarrett D'Amore case (LIST_hyphen): 788*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type) 789*698f87a4SGarrett D'Amore break; 79095c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 791*698f87a4SGarrett D'Amore p->trailspace = 1; 79295c635efSGarrett D'Amore break; 79395c635efSGarrett D'Amore case (LIST_hang): 794*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type) 79595c635efSGarrett D'Amore break; 79695c635efSGarrett D'Amore 79795c635efSGarrett D'Amore /* 79895c635efSGarrett D'Amore * This is ugly. If `-hang' is specified and the body 79995c635efSGarrett D'Amore * is a `Bl' or `Bd', then we want basically to nullify 80095c635efSGarrett D'Amore * the "overstep" effect in term_flushln() and treat 80195c635efSGarrett D'Amore * this as a `-ohang' list instead. 80295c635efSGarrett D'Amore */ 80395c635efSGarrett D'Amore if (n->next->child && 80495c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok || 80595c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok)) 806*698f87a4SGarrett D'Amore break; 807*698f87a4SGarrett D'Amore 808*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG; 809*698f87a4SGarrett D'Amore p->trailspace = 1; 81095c635efSGarrett D'Amore break; 81195c635efSGarrett D'Amore case (LIST_tag): 81295c635efSGarrett D'Amore if (MDOC_HEAD != n->type) 81395c635efSGarrett D'Amore break; 814*698f87a4SGarrett D'Amore 815*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK; 816*698f87a4SGarrett D'Amore p->trailspace = 2; 817*698f87a4SGarrett D'Amore 81895c635efSGarrett D'Amore if (NULL == n->next || NULL == n->next->child) 81995c635efSGarrett D'Amore p->flags |= TERMP_DANGLE; 82095c635efSGarrett D'Amore break; 82195c635efSGarrett D'Amore case (LIST_column): 82295c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 82395c635efSGarrett D'Amore break; 82495c635efSGarrett D'Amore 825*698f87a4SGarrett D'Amore if (NULL == n->next) { 82695c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 827*698f87a4SGarrett D'Amore p->trailspace = 0; 828*698f87a4SGarrett D'Amore } else { 82995c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 830*698f87a4SGarrett D'Amore p->trailspace = 1; 831*698f87a4SGarrett D'Amore } 83295c635efSGarrett D'Amore 83395c635efSGarrett D'Amore break; 83495c635efSGarrett D'Amore case (LIST_diag): 835*698f87a4SGarrett D'Amore if (MDOC_HEAD != n->type) 836*698f87a4SGarrett D'Amore break; 83795c635efSGarrett D'Amore p->flags |= TERMP_NOBREAK; 838*698f87a4SGarrett D'Amore p->trailspace = 1; 83995c635efSGarrett D'Amore break; 84095c635efSGarrett D'Amore default: 84195c635efSGarrett D'Amore break; 84295c635efSGarrett D'Amore } 84395c635efSGarrett D'Amore 84495c635efSGarrett D'Amore /* 84595c635efSGarrett D'Amore * Margin control. Set-head-width lists have their right 84695c635efSGarrett D'Amore * margins shortened. The body for these lists has the offset 84795c635efSGarrett D'Amore * necessarily lengthened. Everybody gets the offset. 84895c635efSGarrett D'Amore */ 84995c635efSGarrett D'Amore 85095c635efSGarrett D'Amore p->offset += offset; 85195c635efSGarrett D'Amore 85295c635efSGarrett D'Amore switch (type) { 85395c635efSGarrett D'Amore case (LIST_hang): 85495c635efSGarrett D'Amore /* 85595c635efSGarrett D'Amore * Same stipulation as above, regarding `-hang'. We 85695c635efSGarrett D'Amore * don't want to recalculate rmargin and offsets when 85795c635efSGarrett D'Amore * using `Bd' or `Bl' within `-hang' overstep lists. 85895c635efSGarrett D'Amore */ 85995c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child && 86095c635efSGarrett D'Amore (MDOC_Bl == n->next->child->tok || 86195c635efSGarrett D'Amore MDOC_Bd == n->next->child->tok)) 86295c635efSGarrett D'Amore break; 86395c635efSGarrett D'Amore /* FALLTHROUGH */ 86495c635efSGarrett D'Amore case (LIST_bullet): 86595c635efSGarrett D'Amore /* FALLTHROUGH */ 86695c635efSGarrett D'Amore case (LIST_dash): 86795c635efSGarrett D'Amore /* FALLTHROUGH */ 86895c635efSGarrett D'Amore case (LIST_enum): 86995c635efSGarrett D'Amore /* FALLTHROUGH */ 87095c635efSGarrett D'Amore case (LIST_hyphen): 87195c635efSGarrett D'Amore /* FALLTHROUGH */ 87295c635efSGarrett D'Amore case (LIST_tag): 87395c635efSGarrett D'Amore assert(width); 87495c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 87595c635efSGarrett D'Amore p->rmargin = p->offset + width; 87695c635efSGarrett D'Amore else 87795c635efSGarrett D'Amore p->offset += width; 87895c635efSGarrett D'Amore break; 87995c635efSGarrett D'Amore case (LIST_column): 88095c635efSGarrett D'Amore assert(width); 88195c635efSGarrett D'Amore p->rmargin = p->offset + width; 88295c635efSGarrett D'Amore /* 88395c635efSGarrett D'Amore * XXX - this behaviour is not documented: the 88495c635efSGarrett D'Amore * right-most column is filled to the right margin. 88595c635efSGarrett D'Amore */ 88695c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 88795c635efSGarrett D'Amore break; 88895c635efSGarrett D'Amore if (NULL == n->next && p->rmargin < p->maxrmargin) 88995c635efSGarrett D'Amore p->rmargin = p->maxrmargin; 89095c635efSGarrett D'Amore break; 89195c635efSGarrett D'Amore default: 89295c635efSGarrett D'Amore break; 89395c635efSGarrett D'Amore } 89495c635efSGarrett D'Amore 89595c635efSGarrett D'Amore /* 89695c635efSGarrett D'Amore * The dash, hyphen, bullet and enum lists all have a special 89795c635efSGarrett D'Amore * HEAD character (temporarily bold, in some cases). 89895c635efSGarrett D'Amore */ 89995c635efSGarrett D'Amore 90095c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 90195c635efSGarrett D'Amore switch (type) { 90295c635efSGarrett D'Amore case (LIST_bullet): 90395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 90495c635efSGarrett D'Amore term_word(p, "\\[bu]"); 90595c635efSGarrett D'Amore term_fontpop(p); 90695c635efSGarrett D'Amore break; 90795c635efSGarrett D'Amore case (LIST_dash): 90895c635efSGarrett D'Amore /* FALLTHROUGH */ 90995c635efSGarrett D'Amore case (LIST_hyphen): 91095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 91195c635efSGarrett D'Amore term_word(p, "\\(hy"); 91295c635efSGarrett D'Amore term_fontpop(p); 91395c635efSGarrett D'Amore break; 91495c635efSGarrett D'Amore case (LIST_enum): 91595c635efSGarrett D'Amore (pair->ppair->ppair->count)++; 91695c635efSGarrett D'Amore snprintf(buf, sizeof(buf), "%d.", 91795c635efSGarrett D'Amore pair->ppair->ppair->count); 91895c635efSGarrett D'Amore term_word(p, buf); 91995c635efSGarrett D'Amore break; 92095c635efSGarrett D'Amore default: 92195c635efSGarrett D'Amore break; 92295c635efSGarrett D'Amore } 92395c635efSGarrett D'Amore 92495c635efSGarrett D'Amore /* 92595c635efSGarrett D'Amore * If we're not going to process our children, indicate so here. 92695c635efSGarrett D'Amore */ 92795c635efSGarrett D'Amore 92895c635efSGarrett D'Amore switch (type) { 92995c635efSGarrett D'Amore case (LIST_bullet): 93095c635efSGarrett D'Amore /* FALLTHROUGH */ 93195c635efSGarrett D'Amore case (LIST_item): 93295c635efSGarrett D'Amore /* FALLTHROUGH */ 93395c635efSGarrett D'Amore case (LIST_dash): 93495c635efSGarrett D'Amore /* FALLTHROUGH */ 93595c635efSGarrett D'Amore case (LIST_hyphen): 93695c635efSGarrett D'Amore /* FALLTHROUGH */ 93795c635efSGarrett D'Amore case (LIST_enum): 93895c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 93995c635efSGarrett D'Amore return(0); 94095c635efSGarrett D'Amore break; 94195c635efSGarrett D'Amore case (LIST_column): 94295c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 94395c635efSGarrett D'Amore return(0); 94495c635efSGarrett D'Amore break; 94595c635efSGarrett D'Amore default: 94695c635efSGarrett D'Amore break; 94795c635efSGarrett D'Amore } 94895c635efSGarrett D'Amore 94995c635efSGarrett D'Amore return(1); 95095c635efSGarrett D'Amore } 95195c635efSGarrett D'Amore 95295c635efSGarrett D'Amore 95395c635efSGarrett D'Amore /* ARGSUSED */ 95495c635efSGarrett D'Amore static void 95595c635efSGarrett D'Amore termp_it_post(DECL_ARGS) 95695c635efSGarrett D'Amore { 95795c635efSGarrett D'Amore enum mdoc_list type; 95895c635efSGarrett D'Amore 95995c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) 96095c635efSGarrett D'Amore return; 96195c635efSGarrett D'Amore 96295c635efSGarrett D'Amore type = n->parent->parent->parent->norm->Bl.type; 96395c635efSGarrett D'Amore 96495c635efSGarrett D'Amore switch (type) { 96595c635efSGarrett D'Amore case (LIST_item): 96695c635efSGarrett D'Amore /* FALLTHROUGH */ 96795c635efSGarrett D'Amore case (LIST_diag): 96895c635efSGarrett D'Amore /* FALLTHROUGH */ 96995c635efSGarrett D'Amore case (LIST_inset): 97095c635efSGarrett D'Amore if (MDOC_BODY == n->type) 97195c635efSGarrett D'Amore term_newln(p); 97295c635efSGarrett D'Amore break; 97395c635efSGarrett D'Amore case (LIST_column): 97495c635efSGarrett D'Amore if (MDOC_BODY == n->type) 97595c635efSGarrett D'Amore term_flushln(p); 97695c635efSGarrett D'Amore break; 97795c635efSGarrett D'Amore default: 97895c635efSGarrett D'Amore term_newln(p); 97995c635efSGarrett D'Amore break; 98095c635efSGarrett D'Amore } 98195c635efSGarrett D'Amore 98295c635efSGarrett D'Amore /* 98395c635efSGarrett D'Amore * Now that our output is flushed, we can reset our tags. Since 98495c635efSGarrett D'Amore * only `It' sets these flags, we're free to assume that nobody 98595c635efSGarrett D'Amore * has munged them in the meanwhile. 98695c635efSGarrett D'Amore */ 98795c635efSGarrett D'Amore 98895c635efSGarrett D'Amore p->flags &= ~TERMP_DANGLE; 98995c635efSGarrett D'Amore p->flags &= ~TERMP_NOBREAK; 99095c635efSGarrett D'Amore p->flags &= ~TERMP_HANG; 991*698f87a4SGarrett D'Amore p->trailspace = 0; 99295c635efSGarrett D'Amore } 99395c635efSGarrett D'Amore 99495c635efSGarrett D'Amore 99595c635efSGarrett D'Amore /* ARGSUSED */ 99695c635efSGarrett D'Amore static int 99795c635efSGarrett D'Amore termp_nm_pre(DECL_ARGS) 99895c635efSGarrett D'Amore { 99995c635efSGarrett D'Amore 1000*698f87a4SGarrett D'Amore if (MDOC_BLOCK == n->type) { 1001*698f87a4SGarrett D'Amore p->flags |= TERMP_PREKEEP; 100295c635efSGarrett D'Amore return(1); 1003*698f87a4SGarrett D'Amore } 100495c635efSGarrett D'Amore 100595c635efSGarrett D'Amore if (MDOC_BODY == n->type) { 100695c635efSGarrett D'Amore if (NULL == n->child) 100795c635efSGarrett D'Amore return(0); 100895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 100995c635efSGarrett D'Amore p->offset += term_len(p, 1) + 1010*698f87a4SGarrett D'Amore (NULL == n->prev->child ? 1011*698f87a4SGarrett D'Amore term_strlen(p, meta->name) : 101295c635efSGarrett D'Amore MDOC_TEXT == n->prev->child->type ? 101395c635efSGarrett D'Amore term_strlen(p, n->prev->child->string) : 101495c635efSGarrett D'Amore term_len(p, 5)); 101595c635efSGarrett D'Amore return(1); 101695c635efSGarrett D'Amore } 101795c635efSGarrett D'Amore 1018*698f87a4SGarrett D'Amore if (NULL == n->child && NULL == meta->name) 101995c635efSGarrett D'Amore return(0); 102095c635efSGarrett D'Amore 102195c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 102295c635efSGarrett D'Amore synopsis_pre(p, n->parent); 102395c635efSGarrett D'Amore 102495c635efSGarrett D'Amore if (MDOC_HEAD == n->type && n->next->child) { 102595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; 1026*698f87a4SGarrett D'Amore p->trailspace = 1; 102795c635efSGarrett D'Amore p->rmargin = p->offset + term_len(p, 1); 102895c635efSGarrett D'Amore if (NULL == n->child) { 1029*698f87a4SGarrett D'Amore p->rmargin += term_strlen(p, meta->name); 103095c635efSGarrett D'Amore } else if (MDOC_TEXT == n->child->type) { 103195c635efSGarrett D'Amore p->rmargin += term_strlen(p, n->child->string); 103295c635efSGarrett D'Amore if (n->child->next) 103395c635efSGarrett D'Amore p->flags |= TERMP_HANG; 103495c635efSGarrett D'Amore } else { 103595c635efSGarrett D'Amore p->rmargin += term_len(p, 5); 103695c635efSGarrett D'Amore p->flags |= TERMP_HANG; 103795c635efSGarrett D'Amore } 103895c635efSGarrett D'Amore } 103995c635efSGarrett D'Amore 104095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 104195c635efSGarrett D'Amore if (NULL == n->child) 1042*698f87a4SGarrett D'Amore term_word(p, meta->name); 104395c635efSGarrett D'Amore return(1); 104495c635efSGarrett D'Amore } 104595c635efSGarrett D'Amore 104695c635efSGarrett D'Amore 104795c635efSGarrett D'Amore /* ARGSUSED */ 104895c635efSGarrett D'Amore static void 104995c635efSGarrett D'Amore termp_nm_post(DECL_ARGS) 105095c635efSGarrett D'Amore { 105195c635efSGarrett D'Amore 1052*698f87a4SGarrett D'Amore if (MDOC_BLOCK == n->type) { 1053*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); 1054*698f87a4SGarrett D'Amore } else if (MDOC_HEAD == n->type && n->next->child) { 105595c635efSGarrett D'Amore term_flushln(p); 105695c635efSGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); 1057*698f87a4SGarrett D'Amore p->trailspace = 0; 105895c635efSGarrett D'Amore } else if (MDOC_BODY == n->type && n->child) 105995c635efSGarrett D'Amore term_flushln(p); 106095c635efSGarrett D'Amore } 106195c635efSGarrett D'Amore 106295c635efSGarrett D'Amore 106395c635efSGarrett D'Amore /* ARGSUSED */ 106495c635efSGarrett D'Amore static int 106595c635efSGarrett D'Amore termp_fl_pre(DECL_ARGS) 106695c635efSGarrett D'Amore { 106795c635efSGarrett D'Amore 106895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 106995c635efSGarrett D'Amore term_word(p, "\\-"); 107095c635efSGarrett D'Amore 107195c635efSGarrett D'Amore if (n->child) 107295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 107395c635efSGarrett D'Amore else if (n->next && n->next->line == n->line) 107495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 107595c635efSGarrett D'Amore 107695c635efSGarrett D'Amore return(1); 107795c635efSGarrett D'Amore } 107895c635efSGarrett D'Amore 107995c635efSGarrett D'Amore 108095c635efSGarrett D'Amore /* ARGSUSED */ 108195c635efSGarrett D'Amore static int 108295c635efSGarrett D'Amore termp__a_pre(DECL_ARGS) 108395c635efSGarrett D'Amore { 108495c635efSGarrett D'Amore 108595c635efSGarrett D'Amore if (n->prev && MDOC__A == n->prev->tok) 108695c635efSGarrett D'Amore if (NULL == n->next || MDOC__A != n->next->tok) 108795c635efSGarrett D'Amore term_word(p, "and"); 108895c635efSGarrett D'Amore 108995c635efSGarrett D'Amore return(1); 109095c635efSGarrett D'Amore } 109195c635efSGarrett D'Amore 109295c635efSGarrett D'Amore 109395c635efSGarrett D'Amore /* ARGSUSED */ 109495c635efSGarrett D'Amore static int 109595c635efSGarrett D'Amore termp_an_pre(DECL_ARGS) 109695c635efSGarrett D'Amore { 109795c635efSGarrett D'Amore 109895c635efSGarrett D'Amore if (NULL == n->child) 109995c635efSGarrett D'Amore return(1); 110095c635efSGarrett D'Amore 110195c635efSGarrett D'Amore /* 110295c635efSGarrett D'Amore * If not in the AUTHORS section, `An -split' will cause 110395c635efSGarrett D'Amore * newlines to occur before the author name. If in the AUTHORS 110495c635efSGarrett D'Amore * section, by default, the first `An' invocation is nosplit, 110595c635efSGarrett D'Amore * then all subsequent ones, regardless of whether interspersed 110695c635efSGarrett D'Amore * with other macros/text, are split. -split, in this case, 110795c635efSGarrett D'Amore * will override the condition of the implied first -nosplit. 110895c635efSGarrett D'Amore */ 110995c635efSGarrett D'Amore 111095c635efSGarrett D'Amore if (n->sec == SEC_AUTHORS) { 111195c635efSGarrett D'Amore if ( ! (TERMP_ANPREC & p->flags)) { 111295c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags) 111395c635efSGarrett D'Amore term_newln(p); 111495c635efSGarrett D'Amore return(1); 111595c635efSGarrett D'Amore } 111695c635efSGarrett D'Amore if (TERMP_NOSPLIT & p->flags) 111795c635efSGarrett D'Amore return(1); 111895c635efSGarrett D'Amore term_newln(p); 111995c635efSGarrett D'Amore return(1); 112095c635efSGarrett D'Amore } 112195c635efSGarrett D'Amore 112295c635efSGarrett D'Amore if (TERMP_SPLIT & p->flags) 112395c635efSGarrett D'Amore term_newln(p); 112495c635efSGarrett D'Amore 112595c635efSGarrett D'Amore return(1); 112695c635efSGarrett D'Amore } 112795c635efSGarrett D'Amore 112895c635efSGarrett D'Amore 112995c635efSGarrett D'Amore /* ARGSUSED */ 113095c635efSGarrett D'Amore static void 113195c635efSGarrett D'Amore termp_an_post(DECL_ARGS) 113295c635efSGarrett D'Amore { 113395c635efSGarrett D'Amore 113495c635efSGarrett D'Amore if (n->child) { 113595c635efSGarrett D'Amore if (SEC_AUTHORS == n->sec) 113695c635efSGarrett D'Amore p->flags |= TERMP_ANPREC; 113795c635efSGarrett D'Amore return; 113895c635efSGarrett D'Amore } 113995c635efSGarrett D'Amore 114095c635efSGarrett D'Amore if (AUTH_split == n->norm->An.auth) { 114195c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPLIT; 114295c635efSGarrett D'Amore p->flags |= TERMP_SPLIT; 114395c635efSGarrett D'Amore } else if (AUTH_nosplit == n->norm->An.auth) { 114495c635efSGarrett D'Amore p->flags &= ~TERMP_SPLIT; 114595c635efSGarrett D'Amore p->flags |= TERMP_NOSPLIT; 114695c635efSGarrett D'Amore } 114795c635efSGarrett D'Amore 114895c635efSGarrett D'Amore } 114995c635efSGarrett D'Amore 115095c635efSGarrett D'Amore 115195c635efSGarrett D'Amore /* ARGSUSED */ 115295c635efSGarrett D'Amore static int 115395c635efSGarrett D'Amore termp_ns_pre(DECL_ARGS) 115495c635efSGarrett D'Amore { 115595c635efSGarrett D'Amore 115695c635efSGarrett D'Amore if ( ! (MDOC_LINE & n->flags)) 115795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 115895c635efSGarrett D'Amore return(1); 115995c635efSGarrett D'Amore } 116095c635efSGarrett D'Amore 116195c635efSGarrett D'Amore 116295c635efSGarrett D'Amore /* ARGSUSED */ 116395c635efSGarrett D'Amore static int 116495c635efSGarrett D'Amore termp_rs_pre(DECL_ARGS) 116595c635efSGarrett D'Amore { 116695c635efSGarrett D'Amore 116795c635efSGarrett D'Amore if (SEC_SEE_ALSO != n->sec) 116895c635efSGarrett D'Amore return(1); 116995c635efSGarrett D'Amore if (MDOC_BLOCK == n->type && n->prev) 117095c635efSGarrett D'Amore term_vspace(p); 117195c635efSGarrett D'Amore return(1); 117295c635efSGarrett D'Amore } 117395c635efSGarrett D'Amore 117495c635efSGarrett D'Amore 117595c635efSGarrett D'Amore /* ARGSUSED */ 117695c635efSGarrett D'Amore static int 117795c635efSGarrett D'Amore termp_rv_pre(DECL_ARGS) 117895c635efSGarrett D'Amore { 117995c635efSGarrett D'Amore int nchild; 118095c635efSGarrett D'Amore 118195c635efSGarrett D'Amore term_newln(p); 118295c635efSGarrett D'Amore term_word(p, "The"); 118395c635efSGarrett D'Amore 118495c635efSGarrett D'Amore nchild = n->nchild; 118595c635efSGarrett D'Amore for (n = n->child; n; n = n->next) { 118695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 118795c635efSGarrett D'Amore term_word(p, n->string); 118895c635efSGarrett D'Amore term_fontpop(p); 118995c635efSGarrett D'Amore 119095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 119195c635efSGarrett D'Amore term_word(p, "()"); 119295c635efSGarrett D'Amore 119395c635efSGarrett D'Amore if (nchild > 2 && n->next) { 119495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 119595c635efSGarrett D'Amore term_word(p, ","); 119695c635efSGarrett D'Amore } 119795c635efSGarrett D'Amore 119895c635efSGarrett D'Amore if (n->next && NULL == n->next->next) 119995c635efSGarrett D'Amore term_word(p, "and"); 120095c635efSGarrett D'Amore } 120195c635efSGarrett D'Amore 120295c635efSGarrett D'Amore if (nchild > 1) 120395c635efSGarrett D'Amore term_word(p, "functions return"); 120495c635efSGarrett D'Amore else 120595c635efSGarrett D'Amore term_word(p, "function returns"); 120695c635efSGarrett D'Amore 120795c635efSGarrett D'Amore term_word(p, "the value 0 if successful; otherwise the value " 120895c635efSGarrett D'Amore "-1 is returned and the global variable"); 120995c635efSGarrett D'Amore 121095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 121195c635efSGarrett D'Amore term_word(p, "errno"); 121295c635efSGarrett D'Amore term_fontpop(p); 121395c635efSGarrett D'Amore 121495c635efSGarrett D'Amore term_word(p, "is set to indicate the error."); 121595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 121695c635efSGarrett D'Amore 121795c635efSGarrett D'Amore return(0); 121895c635efSGarrett D'Amore } 121995c635efSGarrett D'Amore 122095c635efSGarrett D'Amore 122195c635efSGarrett D'Amore /* ARGSUSED */ 122295c635efSGarrett D'Amore static int 122395c635efSGarrett D'Amore termp_ex_pre(DECL_ARGS) 122495c635efSGarrett D'Amore { 122595c635efSGarrett D'Amore int nchild; 122695c635efSGarrett D'Amore 122795c635efSGarrett D'Amore term_newln(p); 122895c635efSGarrett D'Amore term_word(p, "The"); 122995c635efSGarrett D'Amore 123095c635efSGarrett D'Amore nchild = n->nchild; 123195c635efSGarrett D'Amore for (n = n->child; n; n = n->next) { 123295c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 123395c635efSGarrett D'Amore term_word(p, n->string); 123495c635efSGarrett D'Amore term_fontpop(p); 123595c635efSGarrett D'Amore 123695c635efSGarrett D'Amore if (nchild > 2 && n->next) { 123795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 123895c635efSGarrett D'Amore term_word(p, ","); 123995c635efSGarrett D'Amore } 124095c635efSGarrett D'Amore 124195c635efSGarrett D'Amore if (n->next && NULL == n->next->next) 124295c635efSGarrett D'Amore term_word(p, "and"); 124395c635efSGarrett D'Amore } 124495c635efSGarrett D'Amore 124595c635efSGarrett D'Amore if (nchild > 1) 124695c635efSGarrett D'Amore term_word(p, "utilities exit"); 124795c635efSGarrett D'Amore else 124895c635efSGarrett D'Amore term_word(p, "utility exits"); 124995c635efSGarrett D'Amore 125095c635efSGarrett D'Amore term_word(p, "0 on success, and >0 if an error occurs."); 125195c635efSGarrett D'Amore 125295c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 125395c635efSGarrett D'Amore return(0); 125495c635efSGarrett D'Amore } 125595c635efSGarrett D'Amore 125695c635efSGarrett D'Amore 125795c635efSGarrett D'Amore /* ARGSUSED */ 125895c635efSGarrett D'Amore static int 125995c635efSGarrett D'Amore termp_nd_pre(DECL_ARGS) 126095c635efSGarrett D'Amore { 126195c635efSGarrett D'Amore 126295c635efSGarrett D'Amore if (MDOC_BODY != n->type) 126395c635efSGarrett D'Amore return(1); 126495c635efSGarrett D'Amore 126595c635efSGarrett D'Amore #if defined(__OpenBSD__) || defined(__linux__) 126695c635efSGarrett D'Amore term_word(p, "\\(en"); 126795c635efSGarrett D'Amore #else 126895c635efSGarrett D'Amore term_word(p, "\\(em"); 126995c635efSGarrett D'Amore #endif 127095c635efSGarrett D'Amore return(1); 127195c635efSGarrett D'Amore } 127295c635efSGarrett D'Amore 127395c635efSGarrett D'Amore 127495c635efSGarrett D'Amore /* ARGSUSED */ 127595c635efSGarrett D'Amore static int 127695c635efSGarrett D'Amore termp_bl_pre(DECL_ARGS) 127795c635efSGarrett D'Amore { 127895c635efSGarrett D'Amore 127995c635efSGarrett D'Amore return(MDOC_HEAD != n->type); 128095c635efSGarrett D'Amore } 128195c635efSGarrett D'Amore 128295c635efSGarrett D'Amore 128395c635efSGarrett D'Amore /* ARGSUSED */ 128495c635efSGarrett D'Amore static void 128595c635efSGarrett D'Amore termp_bl_post(DECL_ARGS) 128695c635efSGarrett D'Amore { 128795c635efSGarrett D'Amore 128895c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) 128995c635efSGarrett D'Amore term_newln(p); 129095c635efSGarrett D'Amore } 129195c635efSGarrett D'Amore 129295c635efSGarrett D'Amore /* ARGSUSED */ 129395c635efSGarrett D'Amore static int 129495c635efSGarrett D'Amore termp_xr_pre(DECL_ARGS) 129595c635efSGarrett D'Amore { 129695c635efSGarrett D'Amore 129795c635efSGarrett D'Amore if (NULL == (n = n->child)) 129895c635efSGarrett D'Amore return(0); 129995c635efSGarrett D'Amore 130095c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 130195c635efSGarrett D'Amore term_word(p, n->string); 130295c635efSGarrett D'Amore 130395c635efSGarrett D'Amore if (NULL == (n = n->next)) 130495c635efSGarrett D'Amore return(0); 130595c635efSGarrett D'Amore 130695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 130795c635efSGarrett D'Amore term_word(p, "("); 130895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 130995c635efSGarrett D'Amore 131095c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 131195c635efSGarrett D'Amore term_word(p, n->string); 131295c635efSGarrett D'Amore 131395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 131495c635efSGarrett D'Amore term_word(p, ")"); 131595c635efSGarrett D'Amore 131695c635efSGarrett D'Amore return(0); 131795c635efSGarrett D'Amore } 131895c635efSGarrett D'Amore 131995c635efSGarrett D'Amore /* 132095c635efSGarrett D'Amore * This decides how to assert whitespace before any of the SYNOPSIS set 132195c635efSGarrett D'Amore * of macros (which, as in the case of Ft/Fo and Ft/Fn, may contain 132295c635efSGarrett D'Amore * macro combos). 132395c635efSGarrett D'Amore */ 132495c635efSGarrett D'Amore static void 132595c635efSGarrett D'Amore synopsis_pre(struct termp *p, const struct mdoc_node *n) 132695c635efSGarrett D'Amore { 132795c635efSGarrett D'Amore /* 132895c635efSGarrett D'Amore * Obviously, if we're not in a SYNOPSIS or no prior macros 132995c635efSGarrett D'Amore * exist, do nothing. 133095c635efSGarrett D'Amore */ 133195c635efSGarrett D'Amore if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags)) 133295c635efSGarrett D'Amore return; 133395c635efSGarrett D'Amore 133495c635efSGarrett D'Amore /* 133595c635efSGarrett D'Amore * If we're the second in a pair of like elements, emit our 133695c635efSGarrett D'Amore * newline and return. UNLESS we're `Fo', `Fn', `Fn', in which 133795c635efSGarrett D'Amore * case we soldier on. 133895c635efSGarrett D'Amore */ 133995c635efSGarrett D'Amore if (n->prev->tok == n->tok && 134095c635efSGarrett D'Amore MDOC_Ft != n->tok && 134195c635efSGarrett D'Amore MDOC_Fo != n->tok && 134295c635efSGarrett D'Amore MDOC_Fn != n->tok) { 134395c635efSGarrett D'Amore term_newln(p); 134495c635efSGarrett D'Amore return; 134595c635efSGarrett D'Amore } 134695c635efSGarrett D'Amore 134795c635efSGarrett D'Amore /* 134895c635efSGarrett D'Amore * If we're one of the SYNOPSIS set and non-like pair-wise after 134995c635efSGarrett D'Amore * another (or Fn/Fo, which we've let slip through) then assert 135095c635efSGarrett D'Amore * vertical space, else only newline and move on. 135195c635efSGarrett D'Amore */ 135295c635efSGarrett D'Amore switch (n->prev->tok) { 135395c635efSGarrett D'Amore case (MDOC_Fd): 135495c635efSGarrett D'Amore /* FALLTHROUGH */ 135595c635efSGarrett D'Amore case (MDOC_Fn): 135695c635efSGarrett D'Amore /* FALLTHROUGH */ 135795c635efSGarrett D'Amore case (MDOC_Fo): 135895c635efSGarrett D'Amore /* FALLTHROUGH */ 135995c635efSGarrett D'Amore case (MDOC_In): 136095c635efSGarrett D'Amore /* FALLTHROUGH */ 136195c635efSGarrett D'Amore case (MDOC_Vt): 136295c635efSGarrett D'Amore term_vspace(p); 136395c635efSGarrett D'Amore break; 136495c635efSGarrett D'Amore case (MDOC_Ft): 136595c635efSGarrett D'Amore if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { 136695c635efSGarrett D'Amore term_vspace(p); 136795c635efSGarrett D'Amore break; 136895c635efSGarrett D'Amore } 136995c635efSGarrett D'Amore /* FALLTHROUGH */ 137095c635efSGarrett D'Amore default: 137195c635efSGarrett D'Amore term_newln(p); 137295c635efSGarrett D'Amore break; 137395c635efSGarrett D'Amore } 137495c635efSGarrett D'Amore } 137595c635efSGarrett D'Amore 137695c635efSGarrett D'Amore 137795c635efSGarrett D'Amore static int 137895c635efSGarrett D'Amore termp_vt_pre(DECL_ARGS) 137995c635efSGarrett D'Amore { 138095c635efSGarrett D'Amore 138195c635efSGarrett D'Amore if (MDOC_ELEM == n->type) { 138295c635efSGarrett D'Amore synopsis_pre(p, n); 1383*698f87a4SGarrett D'Amore return(termp_under_pre(p, pair, meta, n)); 138495c635efSGarrett D'Amore } else if (MDOC_BLOCK == n->type) { 138595c635efSGarrett D'Amore synopsis_pre(p, n); 138695c635efSGarrett D'Amore return(1); 138795c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type) 138895c635efSGarrett D'Amore return(0); 138995c635efSGarrett D'Amore 1390*698f87a4SGarrett D'Amore return(termp_under_pre(p, pair, meta, n)); 139195c635efSGarrett D'Amore } 139295c635efSGarrett D'Amore 139395c635efSGarrett D'Amore 139495c635efSGarrett D'Amore /* ARGSUSED */ 139595c635efSGarrett D'Amore static int 139695c635efSGarrett D'Amore termp_bold_pre(DECL_ARGS) 139795c635efSGarrett D'Amore { 139895c635efSGarrett D'Amore 139995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 140095c635efSGarrett D'Amore return(1); 140195c635efSGarrett D'Amore } 140295c635efSGarrett D'Amore 140395c635efSGarrett D'Amore 140495c635efSGarrett D'Amore /* ARGSUSED */ 140595c635efSGarrett D'Amore static int 140695c635efSGarrett D'Amore termp_fd_pre(DECL_ARGS) 140795c635efSGarrett D'Amore { 140895c635efSGarrett D'Amore 140995c635efSGarrett D'Amore synopsis_pre(p, n); 1410*698f87a4SGarrett D'Amore return(termp_bold_pre(p, pair, meta, n)); 1411*698f87a4SGarrett D'Amore } 1412*698f87a4SGarrett D'Amore 1413*698f87a4SGarrett D'Amore 1414*698f87a4SGarrett D'Amore /* ARGSUSED */ 1415*698f87a4SGarrett D'Amore static void 1416*698f87a4SGarrett D'Amore termp_fd_post(DECL_ARGS) 1417*698f87a4SGarrett D'Amore { 1418*698f87a4SGarrett D'Amore 1419*698f87a4SGarrett D'Amore term_newln(p); 142095c635efSGarrett D'Amore } 142195c635efSGarrett D'Amore 142295c635efSGarrett D'Amore 142395c635efSGarrett D'Amore /* ARGSUSED */ 142495c635efSGarrett D'Amore static int 142595c635efSGarrett D'Amore termp_sh_pre(DECL_ARGS) 142695c635efSGarrett D'Amore { 142795c635efSGarrett D'Amore 142895c635efSGarrett D'Amore /* No vspace between consecutive `Sh' calls. */ 142995c635efSGarrett D'Amore 143095c635efSGarrett D'Amore switch (n->type) { 143195c635efSGarrett D'Amore case (MDOC_BLOCK): 143295c635efSGarrett D'Amore if (n->prev && MDOC_Sh == n->prev->tok) 143395c635efSGarrett D'Amore if (NULL == n->prev->body->child) 143495c635efSGarrett D'Amore break; 143595c635efSGarrett D'Amore term_vspace(p); 143695c635efSGarrett D'Amore break; 143795c635efSGarrett D'Amore case (MDOC_HEAD): 143895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 143995c635efSGarrett D'Amore break; 144095c635efSGarrett D'Amore case (MDOC_BODY): 144195c635efSGarrett D'Amore p->offset = term_len(p, p->defindent); 1442*698f87a4SGarrett D'Amore if (SEC_AUTHORS == n->sec) 1443*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); 144495c635efSGarrett D'Amore break; 144595c635efSGarrett D'Amore default: 144695c635efSGarrett D'Amore break; 144795c635efSGarrett D'Amore } 144895c635efSGarrett D'Amore return(1); 144995c635efSGarrett D'Amore } 145095c635efSGarrett D'Amore 145195c635efSGarrett D'Amore 145295c635efSGarrett D'Amore /* ARGSUSED */ 145395c635efSGarrett D'Amore static void 145495c635efSGarrett D'Amore termp_sh_post(DECL_ARGS) 145595c635efSGarrett D'Amore { 145695c635efSGarrett D'Amore 145795c635efSGarrett D'Amore switch (n->type) { 145895c635efSGarrett D'Amore case (MDOC_HEAD): 145995c635efSGarrett D'Amore term_newln(p); 146095c635efSGarrett D'Amore break; 146195c635efSGarrett D'Amore case (MDOC_BODY): 146295c635efSGarrett D'Amore term_newln(p); 146395c635efSGarrett D'Amore p->offset = 0; 146495c635efSGarrett D'Amore break; 146595c635efSGarrett D'Amore default: 146695c635efSGarrett D'Amore break; 146795c635efSGarrett D'Amore } 146895c635efSGarrett D'Amore } 146995c635efSGarrett D'Amore 147095c635efSGarrett D'Amore 147195c635efSGarrett D'Amore /* ARGSUSED */ 147295c635efSGarrett D'Amore static int 147395c635efSGarrett D'Amore termp_bt_pre(DECL_ARGS) 147495c635efSGarrett D'Amore { 147595c635efSGarrett D'Amore 147695c635efSGarrett D'Amore term_word(p, "is currently in beta test."); 147795c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 147895c635efSGarrett D'Amore return(0); 147995c635efSGarrett D'Amore } 148095c635efSGarrett D'Amore 148195c635efSGarrett D'Amore 148295c635efSGarrett D'Amore /* ARGSUSED */ 148395c635efSGarrett D'Amore static void 148495c635efSGarrett D'Amore termp_lb_post(DECL_ARGS) 148595c635efSGarrett D'Amore { 148695c635efSGarrett D'Amore 148795c635efSGarrett D'Amore if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags) 148895c635efSGarrett D'Amore term_newln(p); 148995c635efSGarrett D'Amore } 149095c635efSGarrett D'Amore 149195c635efSGarrett D'Amore 149295c635efSGarrett D'Amore /* ARGSUSED */ 149395c635efSGarrett D'Amore static int 149495c635efSGarrett D'Amore termp_ud_pre(DECL_ARGS) 149595c635efSGarrett D'Amore { 149695c635efSGarrett D'Amore 149795c635efSGarrett D'Amore term_word(p, "currently under development."); 149895c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 149995c635efSGarrett D'Amore return(0); 150095c635efSGarrett D'Amore } 150195c635efSGarrett D'Amore 150295c635efSGarrett D'Amore 150395c635efSGarrett D'Amore /* ARGSUSED */ 150495c635efSGarrett D'Amore static int 150595c635efSGarrett D'Amore termp_d1_pre(DECL_ARGS) 150695c635efSGarrett D'Amore { 150795c635efSGarrett D'Amore 150895c635efSGarrett D'Amore if (MDOC_BLOCK != n->type) 150995c635efSGarrett D'Amore return(1); 151095c635efSGarrett D'Amore term_newln(p); 151195c635efSGarrett D'Amore p->offset += term_len(p, p->defindent + 1); 151295c635efSGarrett D'Amore return(1); 151395c635efSGarrett D'Amore } 151495c635efSGarrett D'Amore 151595c635efSGarrett D'Amore 151695c635efSGarrett D'Amore /* ARGSUSED */ 151795c635efSGarrett D'Amore static int 151895c635efSGarrett D'Amore termp_ft_pre(DECL_ARGS) 151995c635efSGarrett D'Amore { 152095c635efSGarrett D'Amore 152195c635efSGarrett D'Amore /* NB: MDOC_LINE does not effect this! */ 152295c635efSGarrett D'Amore synopsis_pre(p, n); 152395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 152495c635efSGarrett D'Amore return(1); 152595c635efSGarrett D'Amore } 152695c635efSGarrett D'Amore 152795c635efSGarrett D'Amore 152895c635efSGarrett D'Amore /* ARGSUSED */ 152995c635efSGarrett D'Amore static int 153095c635efSGarrett D'Amore termp_fn_pre(DECL_ARGS) 153195c635efSGarrett D'Amore { 1532*698f87a4SGarrett D'Amore size_t rmargin = 0; 153395c635efSGarrett D'Amore int pretty; 153495c635efSGarrett D'Amore 153595c635efSGarrett D'Amore pretty = MDOC_SYNPRETTY & n->flags; 153695c635efSGarrett D'Amore 153795c635efSGarrett D'Amore synopsis_pre(p, n); 153895c635efSGarrett D'Amore 153995c635efSGarrett D'Amore if (NULL == (n = n->child)) 154095c635efSGarrett D'Amore return(0); 154195c635efSGarrett D'Amore 1542*698f87a4SGarrett D'Amore if (pretty) { 1543*698f87a4SGarrett D'Amore rmargin = p->rmargin; 1544*698f87a4SGarrett D'Amore p->rmargin = p->offset + term_len(p, 4); 1545*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG; 1546*698f87a4SGarrett D'Amore } 1547*698f87a4SGarrett D'Amore 154895c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 154995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 155095c635efSGarrett D'Amore term_word(p, n->string); 155195c635efSGarrett D'Amore term_fontpop(p); 155295c635efSGarrett D'Amore 1553*698f87a4SGarrett D'Amore if (pretty) { 1554*698f87a4SGarrett D'Amore term_flushln(p); 1555*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); 1556*698f87a4SGarrett D'Amore p->offset = p->rmargin; 1557*698f87a4SGarrett D'Amore p->rmargin = rmargin; 1558*698f87a4SGarrett D'Amore } 1559*698f87a4SGarrett D'Amore 156095c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 156195c635efSGarrett D'Amore term_word(p, "("); 156295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 156395c635efSGarrett D'Amore 156495c635efSGarrett D'Amore for (n = n->next; n; n = n->next) { 156595c635efSGarrett D'Amore assert(MDOC_TEXT == n->type); 156695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1567*698f87a4SGarrett D'Amore if (pretty) 1568*698f87a4SGarrett D'Amore p->flags |= TERMP_NBRWORD; 156995c635efSGarrett D'Amore term_word(p, n->string); 157095c635efSGarrett D'Amore term_fontpop(p); 157195c635efSGarrett D'Amore 157295c635efSGarrett D'Amore if (n->next) { 157395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 157495c635efSGarrett D'Amore term_word(p, ","); 157595c635efSGarrett D'Amore } 157695c635efSGarrett D'Amore } 157795c635efSGarrett D'Amore 157895c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 157995c635efSGarrett D'Amore term_word(p, ")"); 158095c635efSGarrett D'Amore 158195c635efSGarrett D'Amore if (pretty) { 158295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 158395c635efSGarrett D'Amore term_word(p, ";"); 1584*698f87a4SGarrett D'Amore term_flushln(p); 158595c635efSGarrett D'Amore } 158695c635efSGarrett D'Amore 158795c635efSGarrett D'Amore return(0); 158895c635efSGarrett D'Amore } 158995c635efSGarrett D'Amore 159095c635efSGarrett D'Amore 159195c635efSGarrett D'Amore /* ARGSUSED */ 159295c635efSGarrett D'Amore static int 159395c635efSGarrett D'Amore termp_fa_pre(DECL_ARGS) 159495c635efSGarrett D'Amore { 159595c635efSGarrett D'Amore const struct mdoc_node *nn; 159695c635efSGarrett D'Amore 159795c635efSGarrett D'Amore if (n->parent->tok != MDOC_Fo) { 159895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 159995c635efSGarrett D'Amore return(1); 160095c635efSGarrett D'Amore } 160195c635efSGarrett D'Amore 160295c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) { 160395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 1604*698f87a4SGarrett D'Amore p->flags |= TERMP_NBRWORD; 160595c635efSGarrett D'Amore term_word(p, nn->string); 160695c635efSGarrett D'Amore term_fontpop(p); 160795c635efSGarrett D'Amore 1608*698f87a4SGarrett D'Amore if (nn->next || (n->next && n->next->tok == MDOC_Fa)) { 160995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 161095c635efSGarrett D'Amore term_word(p, ","); 161195c635efSGarrett D'Amore } 161295c635efSGarrett D'Amore } 161395c635efSGarrett D'Amore 161495c635efSGarrett D'Amore return(0); 161595c635efSGarrett D'Amore } 161695c635efSGarrett D'Amore 161795c635efSGarrett D'Amore 161895c635efSGarrett D'Amore /* ARGSUSED */ 161995c635efSGarrett D'Amore static int 162095c635efSGarrett D'Amore termp_bd_pre(DECL_ARGS) 162195c635efSGarrett D'Amore { 162295c635efSGarrett D'Amore size_t tabwidth, rm, rmax; 1623*698f87a4SGarrett D'Amore struct mdoc_node *nn; 162495c635efSGarrett D'Amore 162595c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 162695c635efSGarrett D'Amore print_bvspace(p, n, n); 162795c635efSGarrett D'Amore return(1); 162895c635efSGarrett D'Amore } else if (MDOC_HEAD == n->type) 162995c635efSGarrett D'Amore return(0); 163095c635efSGarrett D'Amore 163195c635efSGarrett D'Amore if (n->norm->Bd.offs) 163295c635efSGarrett D'Amore p->offset += a2offs(p, n->norm->Bd.offs); 163395c635efSGarrett D'Amore 163495c635efSGarrett D'Amore /* 163595c635efSGarrett D'Amore * If -ragged or -filled are specified, the block does nothing 163695c635efSGarrett D'Amore * but change the indentation. If -unfilled or -literal are 163795c635efSGarrett D'Amore * specified, text is printed exactly as entered in the display: 163895c635efSGarrett D'Amore * for macro lines, a newline is appended to the line. Blank 163995c635efSGarrett D'Amore * lines are allowed. 164095c635efSGarrett D'Amore */ 164195c635efSGarrett D'Amore 164295c635efSGarrett D'Amore if (DISP_literal != n->norm->Bd.type && 164395c635efSGarrett D'Amore DISP_unfilled != n->norm->Bd.type) 164495c635efSGarrett D'Amore return(1); 164595c635efSGarrett D'Amore 164695c635efSGarrett D'Amore tabwidth = p->tabwidth; 164795c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type) 164895c635efSGarrett D'Amore p->tabwidth = term_len(p, 8); 164995c635efSGarrett D'Amore 165095c635efSGarrett D'Amore rm = p->rmargin; 165195c635efSGarrett D'Amore rmax = p->maxrmargin; 165295c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN; 165395c635efSGarrett D'Amore 165495c635efSGarrett D'Amore for (nn = n->child; nn; nn = nn->next) { 1655*698f87a4SGarrett D'Amore print_mdoc_node(p, pair, meta, nn); 165695c635efSGarrett D'Amore /* 165795c635efSGarrett D'Amore * If the printed node flushes its own line, then we 165895c635efSGarrett D'Amore * needn't do it here as well. This is hacky, but the 165995c635efSGarrett D'Amore * notion of selective eoln whitespace is pretty dumb 166095c635efSGarrett D'Amore * anyway, so don't sweat it. 166195c635efSGarrett D'Amore */ 166295c635efSGarrett D'Amore switch (nn->tok) { 166395c635efSGarrett D'Amore case (MDOC_Sm): 166495c635efSGarrett D'Amore /* FALLTHROUGH */ 166595c635efSGarrett D'Amore case (MDOC_br): 166695c635efSGarrett D'Amore /* FALLTHROUGH */ 166795c635efSGarrett D'Amore case (MDOC_sp): 166895c635efSGarrett D'Amore /* FALLTHROUGH */ 166995c635efSGarrett D'Amore case (MDOC_Bl): 167095c635efSGarrett D'Amore /* FALLTHROUGH */ 167195c635efSGarrett D'Amore case (MDOC_D1): 167295c635efSGarrett D'Amore /* FALLTHROUGH */ 167395c635efSGarrett D'Amore case (MDOC_Dl): 167495c635efSGarrett D'Amore /* FALLTHROUGH */ 167595c635efSGarrett D'Amore case (MDOC_Lp): 167695c635efSGarrett D'Amore /* FALLTHROUGH */ 167795c635efSGarrett D'Amore case (MDOC_Pp): 167895c635efSGarrett D'Amore continue; 167995c635efSGarrett D'Amore default: 168095c635efSGarrett D'Amore break; 168195c635efSGarrett D'Amore } 168295c635efSGarrett D'Amore if (nn->next && nn->next->line == nn->line) 168395c635efSGarrett D'Amore continue; 168495c635efSGarrett D'Amore term_flushln(p); 168595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 168695c635efSGarrett D'Amore } 168795c635efSGarrett D'Amore 168895c635efSGarrett D'Amore p->tabwidth = tabwidth; 168995c635efSGarrett D'Amore p->rmargin = rm; 169095c635efSGarrett D'Amore p->maxrmargin = rmax; 169195c635efSGarrett D'Amore return(0); 169295c635efSGarrett D'Amore } 169395c635efSGarrett D'Amore 169495c635efSGarrett D'Amore 169595c635efSGarrett D'Amore /* ARGSUSED */ 169695c635efSGarrett D'Amore static void 169795c635efSGarrett D'Amore termp_bd_post(DECL_ARGS) 169895c635efSGarrett D'Amore { 169995c635efSGarrett D'Amore size_t rm, rmax; 170095c635efSGarrett D'Amore 170195c635efSGarrett D'Amore if (MDOC_BODY != n->type) 170295c635efSGarrett D'Amore return; 170395c635efSGarrett D'Amore 170495c635efSGarrett D'Amore rm = p->rmargin; 170595c635efSGarrett D'Amore rmax = p->maxrmargin; 170695c635efSGarrett D'Amore 170795c635efSGarrett D'Amore if (DISP_literal == n->norm->Bd.type || 170895c635efSGarrett D'Amore DISP_unfilled == n->norm->Bd.type) 170995c635efSGarrett D'Amore p->rmargin = p->maxrmargin = TERM_MAXMARGIN; 171095c635efSGarrett D'Amore 171195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 171295c635efSGarrett D'Amore term_newln(p); 171395c635efSGarrett D'Amore 171495c635efSGarrett D'Amore p->rmargin = rm; 171595c635efSGarrett D'Amore p->maxrmargin = rmax; 171695c635efSGarrett D'Amore } 171795c635efSGarrett D'Amore 171895c635efSGarrett D'Amore 171995c635efSGarrett D'Amore /* ARGSUSED */ 172095c635efSGarrett D'Amore static int 172195c635efSGarrett D'Amore termp_bx_pre(DECL_ARGS) 172295c635efSGarrett D'Amore { 172395c635efSGarrett D'Amore 172495c635efSGarrett D'Amore if (NULL != (n = n->child)) { 172595c635efSGarrett D'Amore term_word(p, n->string); 172695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 172795c635efSGarrett D'Amore term_word(p, "BSD"); 172895c635efSGarrett D'Amore } else { 172995c635efSGarrett D'Amore term_word(p, "BSD"); 173095c635efSGarrett D'Amore return(0); 173195c635efSGarrett D'Amore } 173295c635efSGarrett D'Amore 173395c635efSGarrett D'Amore if (NULL != (n = n->next)) { 173495c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 173595c635efSGarrett D'Amore term_word(p, "-"); 173695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 173795c635efSGarrett D'Amore term_word(p, n->string); 173895c635efSGarrett D'Amore } 173995c635efSGarrett D'Amore 174095c635efSGarrett D'Amore return(0); 174195c635efSGarrett D'Amore } 174295c635efSGarrett D'Amore 174395c635efSGarrett D'Amore 174495c635efSGarrett D'Amore /* ARGSUSED */ 174595c635efSGarrett D'Amore static int 174695c635efSGarrett D'Amore termp_xx_pre(DECL_ARGS) 174795c635efSGarrett D'Amore { 174895c635efSGarrett D'Amore const char *pp; 174995c635efSGarrett D'Amore int flags; 175095c635efSGarrett D'Amore 175195c635efSGarrett D'Amore pp = NULL; 175295c635efSGarrett D'Amore switch (n->tok) { 175395c635efSGarrett D'Amore case (MDOC_Bsx): 175495c635efSGarrett D'Amore pp = "BSD/OS"; 175595c635efSGarrett D'Amore break; 175695c635efSGarrett D'Amore case (MDOC_Dx): 175795c635efSGarrett D'Amore pp = "DragonFly"; 175895c635efSGarrett D'Amore break; 175995c635efSGarrett D'Amore case (MDOC_Fx): 176095c635efSGarrett D'Amore pp = "FreeBSD"; 176195c635efSGarrett D'Amore break; 176295c635efSGarrett D'Amore case (MDOC_Nx): 176395c635efSGarrett D'Amore pp = "NetBSD"; 176495c635efSGarrett D'Amore break; 176595c635efSGarrett D'Amore case (MDOC_Ox): 176695c635efSGarrett D'Amore pp = "OpenBSD"; 176795c635efSGarrett D'Amore break; 176895c635efSGarrett D'Amore case (MDOC_Ux): 176995c635efSGarrett D'Amore pp = "UNIX"; 177095c635efSGarrett D'Amore break; 177195c635efSGarrett D'Amore default: 1772*698f87a4SGarrett D'Amore abort(); 1773*698f87a4SGarrett D'Amore /* NOTREACHED */ 177495c635efSGarrett D'Amore } 177595c635efSGarrett D'Amore 177695c635efSGarrett D'Amore term_word(p, pp); 177795c635efSGarrett D'Amore if (n->child) { 177895c635efSGarrett D'Amore flags = p->flags; 177995c635efSGarrett D'Amore p->flags |= TERMP_KEEP; 178095c635efSGarrett D'Amore term_word(p, n->child->string); 178195c635efSGarrett D'Amore p->flags = flags; 178295c635efSGarrett D'Amore } 178395c635efSGarrett D'Amore return(0); 178495c635efSGarrett D'Amore } 178595c635efSGarrett D'Amore 178695c635efSGarrett D'Amore 178795c635efSGarrett D'Amore /* ARGSUSED */ 178895c635efSGarrett D'Amore static void 178995c635efSGarrett D'Amore termp_pf_post(DECL_ARGS) 179095c635efSGarrett D'Amore { 179195c635efSGarrett D'Amore 179295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 179395c635efSGarrett D'Amore } 179495c635efSGarrett D'Amore 179595c635efSGarrett D'Amore 179695c635efSGarrett D'Amore /* ARGSUSED */ 179795c635efSGarrett D'Amore static int 179895c635efSGarrett D'Amore termp_ss_pre(DECL_ARGS) 179995c635efSGarrett D'Amore { 180095c635efSGarrett D'Amore 180195c635efSGarrett D'Amore switch (n->type) { 180295c635efSGarrett D'Amore case (MDOC_BLOCK): 180395c635efSGarrett D'Amore term_newln(p); 180495c635efSGarrett D'Amore if (n->prev) 180595c635efSGarrett D'Amore term_vspace(p); 180695c635efSGarrett D'Amore break; 180795c635efSGarrett D'Amore case (MDOC_HEAD): 180895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 180995c635efSGarrett D'Amore p->offset = term_len(p, (p->defindent+1)/2); 181095c635efSGarrett D'Amore break; 181195c635efSGarrett D'Amore default: 181295c635efSGarrett D'Amore break; 181395c635efSGarrett D'Amore } 181495c635efSGarrett D'Amore 181595c635efSGarrett D'Amore return(1); 181695c635efSGarrett D'Amore } 181795c635efSGarrett D'Amore 181895c635efSGarrett D'Amore 181995c635efSGarrett D'Amore /* ARGSUSED */ 182095c635efSGarrett D'Amore static void 182195c635efSGarrett D'Amore termp_ss_post(DECL_ARGS) 182295c635efSGarrett D'Amore { 182395c635efSGarrett D'Amore 182495c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 182595c635efSGarrett D'Amore term_newln(p); 182695c635efSGarrett D'Amore } 182795c635efSGarrett D'Amore 182895c635efSGarrett D'Amore 182995c635efSGarrett D'Amore /* ARGSUSED */ 183095c635efSGarrett D'Amore static int 183195c635efSGarrett D'Amore termp_cd_pre(DECL_ARGS) 183295c635efSGarrett D'Amore { 183395c635efSGarrett D'Amore 183495c635efSGarrett D'Amore synopsis_pre(p, n); 183595c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 183695c635efSGarrett D'Amore return(1); 183795c635efSGarrett D'Amore } 183895c635efSGarrett D'Amore 183995c635efSGarrett D'Amore 184095c635efSGarrett D'Amore /* ARGSUSED */ 184195c635efSGarrett D'Amore static int 184295c635efSGarrett D'Amore termp_in_pre(DECL_ARGS) 184395c635efSGarrett D'Amore { 184495c635efSGarrett D'Amore 184595c635efSGarrett D'Amore synopsis_pre(p, n); 184695c635efSGarrett D'Amore 184795c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags) { 184895c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 184995c635efSGarrett D'Amore term_word(p, "#include"); 185095c635efSGarrett D'Amore term_word(p, "<"); 185195c635efSGarrett D'Amore } else { 185295c635efSGarrett D'Amore term_word(p, "<"); 185395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 185495c635efSGarrett D'Amore } 185595c635efSGarrett D'Amore 185695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 185795c635efSGarrett D'Amore return(1); 185895c635efSGarrett D'Amore } 185995c635efSGarrett D'Amore 186095c635efSGarrett D'Amore 186195c635efSGarrett D'Amore /* ARGSUSED */ 186295c635efSGarrett D'Amore static void 186395c635efSGarrett D'Amore termp_in_post(DECL_ARGS) 186495c635efSGarrett D'Amore { 186595c635efSGarrett D'Amore 186695c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) 186795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 186895c635efSGarrett D'Amore 186995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 187095c635efSGarrett D'Amore term_word(p, ">"); 187195c635efSGarrett D'Amore 187295c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) 187395c635efSGarrett D'Amore term_fontpop(p); 187495c635efSGarrett D'Amore } 187595c635efSGarrett D'Amore 187695c635efSGarrett D'Amore 187795c635efSGarrett D'Amore /* ARGSUSED */ 187895c635efSGarrett D'Amore static int 187995c635efSGarrett D'Amore termp_sp_pre(DECL_ARGS) 188095c635efSGarrett D'Amore { 188195c635efSGarrett D'Amore size_t i, len; 188295c635efSGarrett D'Amore 188395c635efSGarrett D'Amore switch (n->tok) { 188495c635efSGarrett D'Amore case (MDOC_sp): 188595c635efSGarrett D'Amore len = n->child ? a2height(p, n->child->string) : 1; 188695c635efSGarrett D'Amore break; 188795c635efSGarrett D'Amore case (MDOC_br): 188895c635efSGarrett D'Amore len = 0; 188995c635efSGarrett D'Amore break; 189095c635efSGarrett D'Amore default: 189195c635efSGarrett D'Amore len = 1; 189295c635efSGarrett D'Amore break; 189395c635efSGarrett D'Amore } 189495c635efSGarrett D'Amore 189595c635efSGarrett D'Amore if (0 == len) 189695c635efSGarrett D'Amore term_newln(p); 189795c635efSGarrett D'Amore for (i = 0; i < len; i++) 189895c635efSGarrett D'Amore term_vspace(p); 189995c635efSGarrett D'Amore 190095c635efSGarrett D'Amore return(0); 190195c635efSGarrett D'Amore } 190295c635efSGarrett D'Amore 190395c635efSGarrett D'Amore 190495c635efSGarrett D'Amore /* ARGSUSED */ 190595c635efSGarrett D'Amore static int 190695c635efSGarrett D'Amore termp_quote_pre(DECL_ARGS) 190795c635efSGarrett D'Amore { 190895c635efSGarrett D'Amore 190995c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type) 191095c635efSGarrett D'Amore return(1); 191195c635efSGarrett D'Amore 191295c635efSGarrett D'Amore switch (n->tok) { 191395c635efSGarrett D'Amore case (MDOC_Ao): 191495c635efSGarrett D'Amore /* FALLTHROUGH */ 191595c635efSGarrett D'Amore case (MDOC_Aq): 191695c635efSGarrett D'Amore term_word(p, "<"); 191795c635efSGarrett D'Amore break; 191895c635efSGarrett D'Amore case (MDOC_Bro): 191995c635efSGarrett D'Amore /* FALLTHROUGH */ 192095c635efSGarrett D'Amore case (MDOC_Brq): 192195c635efSGarrett D'Amore term_word(p, "{"); 192295c635efSGarrett D'Amore break; 192395c635efSGarrett D'Amore case (MDOC_Oo): 192495c635efSGarrett D'Amore /* FALLTHROUGH */ 192595c635efSGarrett D'Amore case (MDOC_Op): 192695c635efSGarrett D'Amore /* FALLTHROUGH */ 192795c635efSGarrett D'Amore case (MDOC_Bo): 192895c635efSGarrett D'Amore /* FALLTHROUGH */ 192995c635efSGarrett D'Amore case (MDOC_Bq): 193095c635efSGarrett D'Amore term_word(p, "["); 193195c635efSGarrett D'Amore break; 193295c635efSGarrett D'Amore case (MDOC_Do): 193395c635efSGarrett D'Amore /* FALLTHROUGH */ 193495c635efSGarrett D'Amore case (MDOC_Dq): 1935*698f87a4SGarrett D'Amore term_word(p, "\\(lq"); 193695c635efSGarrett D'Amore break; 193795c635efSGarrett D'Amore case (MDOC_Eo): 193895c635efSGarrett D'Amore break; 193995c635efSGarrett D'Amore case (MDOC_Po): 194095c635efSGarrett D'Amore /* FALLTHROUGH */ 194195c635efSGarrett D'Amore case (MDOC_Pq): 194295c635efSGarrett D'Amore term_word(p, "("); 194395c635efSGarrett D'Amore break; 194495c635efSGarrett D'Amore case (MDOC__T): 194595c635efSGarrett D'Amore /* FALLTHROUGH */ 194695c635efSGarrett D'Amore case (MDOC_Qo): 194795c635efSGarrett D'Amore /* FALLTHROUGH */ 194895c635efSGarrett D'Amore case (MDOC_Qq): 194995c635efSGarrett D'Amore term_word(p, "\""); 195095c635efSGarrett D'Amore break; 195195c635efSGarrett D'Amore case (MDOC_Ql): 195295c635efSGarrett D'Amore /* FALLTHROUGH */ 195395c635efSGarrett D'Amore case (MDOC_So): 195495c635efSGarrett D'Amore /* FALLTHROUGH */ 195595c635efSGarrett D'Amore case (MDOC_Sq): 1956*698f87a4SGarrett D'Amore term_word(p, "\\(oq"); 195795c635efSGarrett D'Amore break; 195895c635efSGarrett D'Amore default: 195995c635efSGarrett D'Amore abort(); 196095c635efSGarrett D'Amore /* NOTREACHED */ 196195c635efSGarrett D'Amore } 196295c635efSGarrett D'Amore 196395c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 196495c635efSGarrett D'Amore return(1); 196595c635efSGarrett D'Amore } 196695c635efSGarrett D'Amore 196795c635efSGarrett D'Amore 196895c635efSGarrett D'Amore /* ARGSUSED */ 196995c635efSGarrett D'Amore static void 197095c635efSGarrett D'Amore termp_quote_post(DECL_ARGS) 197195c635efSGarrett D'Amore { 197295c635efSGarrett D'Amore 197395c635efSGarrett D'Amore if (MDOC_BODY != n->type && MDOC_ELEM != n->type) 197495c635efSGarrett D'Amore return; 197595c635efSGarrett D'Amore 197695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 197795c635efSGarrett D'Amore 197895c635efSGarrett D'Amore switch (n->tok) { 197995c635efSGarrett D'Amore case (MDOC_Ao): 198095c635efSGarrett D'Amore /* FALLTHROUGH */ 198195c635efSGarrett D'Amore case (MDOC_Aq): 198295c635efSGarrett D'Amore term_word(p, ">"); 198395c635efSGarrett D'Amore break; 198495c635efSGarrett D'Amore case (MDOC_Bro): 198595c635efSGarrett D'Amore /* FALLTHROUGH */ 198695c635efSGarrett D'Amore case (MDOC_Brq): 198795c635efSGarrett D'Amore term_word(p, "}"); 198895c635efSGarrett D'Amore break; 198995c635efSGarrett D'Amore case (MDOC_Oo): 199095c635efSGarrett D'Amore /* FALLTHROUGH */ 199195c635efSGarrett D'Amore case (MDOC_Op): 199295c635efSGarrett D'Amore /* FALLTHROUGH */ 199395c635efSGarrett D'Amore case (MDOC_Bo): 199495c635efSGarrett D'Amore /* FALLTHROUGH */ 199595c635efSGarrett D'Amore case (MDOC_Bq): 199695c635efSGarrett D'Amore term_word(p, "]"); 199795c635efSGarrett D'Amore break; 199895c635efSGarrett D'Amore case (MDOC_Do): 199995c635efSGarrett D'Amore /* FALLTHROUGH */ 200095c635efSGarrett D'Amore case (MDOC_Dq): 2001*698f87a4SGarrett D'Amore term_word(p, "\\(rq"); 200295c635efSGarrett D'Amore break; 200395c635efSGarrett D'Amore case (MDOC_Eo): 200495c635efSGarrett D'Amore break; 200595c635efSGarrett D'Amore case (MDOC_Po): 200695c635efSGarrett D'Amore /* FALLTHROUGH */ 200795c635efSGarrett D'Amore case (MDOC_Pq): 200895c635efSGarrett D'Amore term_word(p, ")"); 200995c635efSGarrett D'Amore break; 201095c635efSGarrett D'Amore case (MDOC__T): 201195c635efSGarrett D'Amore /* FALLTHROUGH */ 201295c635efSGarrett D'Amore case (MDOC_Qo): 201395c635efSGarrett D'Amore /* FALLTHROUGH */ 201495c635efSGarrett D'Amore case (MDOC_Qq): 201595c635efSGarrett D'Amore term_word(p, "\""); 201695c635efSGarrett D'Amore break; 201795c635efSGarrett D'Amore case (MDOC_Ql): 201895c635efSGarrett D'Amore /* FALLTHROUGH */ 201995c635efSGarrett D'Amore case (MDOC_So): 202095c635efSGarrett D'Amore /* FALLTHROUGH */ 202195c635efSGarrett D'Amore case (MDOC_Sq): 2022*698f87a4SGarrett D'Amore term_word(p, "\\(cq"); 202395c635efSGarrett D'Amore break; 202495c635efSGarrett D'Amore default: 202595c635efSGarrett D'Amore abort(); 202695c635efSGarrett D'Amore /* NOTREACHED */ 202795c635efSGarrett D'Amore } 202895c635efSGarrett D'Amore } 202995c635efSGarrett D'Amore 203095c635efSGarrett D'Amore 203195c635efSGarrett D'Amore /* ARGSUSED */ 203295c635efSGarrett D'Amore static int 203395c635efSGarrett D'Amore termp_fo_pre(DECL_ARGS) 203495c635efSGarrett D'Amore { 2035*698f87a4SGarrett D'Amore size_t rmargin = 0; 2036*698f87a4SGarrett D'Amore int pretty; 2037*698f87a4SGarrett D'Amore 2038*698f87a4SGarrett D'Amore pretty = MDOC_SYNPRETTY & n->flags; 203995c635efSGarrett D'Amore 204095c635efSGarrett D'Amore if (MDOC_BLOCK == n->type) { 204195c635efSGarrett D'Amore synopsis_pre(p, n); 204295c635efSGarrett D'Amore return(1); 204395c635efSGarrett D'Amore } else if (MDOC_BODY == n->type) { 2044*698f87a4SGarrett D'Amore if (pretty) { 2045*698f87a4SGarrett D'Amore rmargin = p->rmargin; 2046*698f87a4SGarrett D'Amore p->rmargin = p->offset + term_len(p, 4); 2047*698f87a4SGarrett D'Amore p->flags |= TERMP_NOBREAK | TERMP_HANG; 2048*698f87a4SGarrett D'Amore } 204995c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 205095c635efSGarrett D'Amore term_word(p, "("); 205195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 2052*698f87a4SGarrett D'Amore if (pretty) { 2053*698f87a4SGarrett D'Amore term_flushln(p); 2054*698f87a4SGarrett D'Amore p->flags &= ~(TERMP_NOBREAK | TERMP_HANG); 2055*698f87a4SGarrett D'Amore p->offset = p->rmargin; 2056*698f87a4SGarrett D'Amore p->rmargin = rmargin; 2057*698f87a4SGarrett D'Amore } 205895c635efSGarrett D'Amore return(1); 205995c635efSGarrett D'Amore } 206095c635efSGarrett D'Amore 206195c635efSGarrett D'Amore if (NULL == n->child) 206295c635efSGarrett D'Amore return(0); 206395c635efSGarrett D'Amore 206495c635efSGarrett D'Amore /* XXX: we drop non-initial arguments as per groff. */ 206595c635efSGarrett D'Amore 206695c635efSGarrett D'Amore assert(n->child->string); 206795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 206895c635efSGarrett D'Amore term_word(p, n->child->string); 206995c635efSGarrett D'Amore return(0); 207095c635efSGarrett D'Amore } 207195c635efSGarrett D'Amore 207295c635efSGarrett D'Amore 207395c635efSGarrett D'Amore /* ARGSUSED */ 207495c635efSGarrett D'Amore static void 207595c635efSGarrett D'Amore termp_fo_post(DECL_ARGS) 207695c635efSGarrett D'Amore { 207795c635efSGarrett D'Amore 207895c635efSGarrett D'Amore if (MDOC_BODY != n->type) 207995c635efSGarrett D'Amore return; 208095c635efSGarrett D'Amore 208195c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 208295c635efSGarrett D'Amore term_word(p, ")"); 208395c635efSGarrett D'Amore 208495c635efSGarrett D'Amore if (MDOC_SYNPRETTY & n->flags) { 208595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 208695c635efSGarrett D'Amore term_word(p, ";"); 2087*698f87a4SGarrett D'Amore term_flushln(p); 208895c635efSGarrett D'Amore } 208995c635efSGarrett D'Amore } 209095c635efSGarrett D'Amore 209195c635efSGarrett D'Amore 209295c635efSGarrett D'Amore /* ARGSUSED */ 209395c635efSGarrett D'Amore static int 209495c635efSGarrett D'Amore termp_bf_pre(DECL_ARGS) 209595c635efSGarrett D'Amore { 209695c635efSGarrett D'Amore 209795c635efSGarrett D'Amore if (MDOC_HEAD == n->type) 209895c635efSGarrett D'Amore return(0); 2099*698f87a4SGarrett D'Amore else if (MDOC_BODY != n->type) 210095c635efSGarrett D'Amore return(1); 210195c635efSGarrett D'Amore 210295c635efSGarrett D'Amore if (FONT_Em == n->norm->Bf.font) 210395c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 210495c635efSGarrett D'Amore else if (FONT_Sy == n->norm->Bf.font) 210595c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 210695c635efSGarrett D'Amore else 210795c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE); 210895c635efSGarrett D'Amore 210995c635efSGarrett D'Amore return(1); 211095c635efSGarrett D'Amore } 211195c635efSGarrett D'Amore 211295c635efSGarrett D'Amore 211395c635efSGarrett D'Amore /* ARGSUSED */ 211495c635efSGarrett D'Amore static int 211595c635efSGarrett D'Amore termp_sm_pre(DECL_ARGS) 211695c635efSGarrett D'Amore { 211795c635efSGarrett D'Amore 211895c635efSGarrett D'Amore assert(n->child && MDOC_TEXT == n->child->type); 211995c635efSGarrett D'Amore if (0 == strcmp("on", n->child->string)) { 212095c635efSGarrett D'Amore if (p->col) 212195c635efSGarrett D'Amore p->flags &= ~TERMP_NOSPACE; 212295c635efSGarrett D'Amore p->flags &= ~TERMP_NONOSPACE; 212395c635efSGarrett D'Amore } else 212495c635efSGarrett D'Amore p->flags |= TERMP_NONOSPACE; 212595c635efSGarrett D'Amore 212695c635efSGarrett D'Amore return(0); 212795c635efSGarrett D'Amore } 212895c635efSGarrett D'Amore 212995c635efSGarrett D'Amore 213095c635efSGarrett D'Amore /* ARGSUSED */ 213195c635efSGarrett D'Amore static int 213295c635efSGarrett D'Amore termp_ap_pre(DECL_ARGS) 213395c635efSGarrett D'Amore { 213495c635efSGarrett D'Amore 213595c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 213695c635efSGarrett D'Amore term_word(p, "'"); 213795c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 213895c635efSGarrett D'Amore return(1); 213995c635efSGarrett D'Amore } 214095c635efSGarrett D'Amore 214195c635efSGarrett D'Amore 214295c635efSGarrett D'Amore /* ARGSUSED */ 214395c635efSGarrett D'Amore static void 214495c635efSGarrett D'Amore termp____post(DECL_ARGS) 214595c635efSGarrett D'Amore { 214695c635efSGarrett D'Amore 214795c635efSGarrett D'Amore /* 214895c635efSGarrett D'Amore * Handle lists of authors. In general, print each followed by 214995c635efSGarrett D'Amore * a comma. Don't print the comma if there are only two 215095c635efSGarrett D'Amore * authors. 215195c635efSGarrett D'Amore */ 215295c635efSGarrett D'Amore if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok) 215395c635efSGarrett D'Amore if (NULL == n->next->next || MDOC__A != n->next->next->tok) 215495c635efSGarrett D'Amore if (NULL == n->prev || MDOC__A != n->prev->tok) 215595c635efSGarrett D'Amore return; 215695c635efSGarrett D'Amore 215795c635efSGarrett D'Amore /* TODO: %U. */ 215895c635efSGarrett D'Amore 215995c635efSGarrett D'Amore if (NULL == n->parent || MDOC_Rs != n->parent->tok) 216095c635efSGarrett D'Amore return; 216195c635efSGarrett D'Amore 216295c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 216395c635efSGarrett D'Amore if (NULL == n->next) { 216495c635efSGarrett D'Amore term_word(p, "."); 216595c635efSGarrett D'Amore p->flags |= TERMP_SENTENCE; 216695c635efSGarrett D'Amore } else 216795c635efSGarrett D'Amore term_word(p, ","); 216895c635efSGarrett D'Amore } 216995c635efSGarrett D'Amore 217095c635efSGarrett D'Amore 217195c635efSGarrett D'Amore /* ARGSUSED */ 217295c635efSGarrett D'Amore static int 217395c635efSGarrett D'Amore termp_li_pre(DECL_ARGS) 217495c635efSGarrett D'Amore { 217595c635efSGarrett D'Amore 217695c635efSGarrett D'Amore term_fontpush(p, TERMFONT_NONE); 217795c635efSGarrett D'Amore return(1); 217895c635efSGarrett D'Amore } 217995c635efSGarrett D'Amore 218095c635efSGarrett D'Amore 218195c635efSGarrett D'Amore /* ARGSUSED */ 218295c635efSGarrett D'Amore static int 218395c635efSGarrett D'Amore termp_lk_pre(DECL_ARGS) 218495c635efSGarrett D'Amore { 2185*698f87a4SGarrett D'Amore const struct mdoc_node *link, *descr; 218695c635efSGarrett D'Amore 2187*698f87a4SGarrett D'Amore if (NULL == (link = n->child)) 2188*698f87a4SGarrett D'Amore return(0); 2189*698f87a4SGarrett D'Amore 2190*698f87a4SGarrett D'Amore if (NULL != (descr = link->next)) { 219195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 2192*698f87a4SGarrett D'Amore while (NULL != descr) { 2193*698f87a4SGarrett D'Amore term_word(p, descr->string); 2194*698f87a4SGarrett D'Amore descr = descr->next; 2195*698f87a4SGarrett D'Amore } 219695c635efSGarrett D'Amore p->flags |= TERMP_NOSPACE; 219795c635efSGarrett D'Amore term_word(p, ":"); 2198*698f87a4SGarrett D'Amore term_fontpop(p); 2199*698f87a4SGarrett D'Amore } 220095c635efSGarrett D'Amore 220195c635efSGarrett D'Amore term_fontpush(p, TERMFONT_BOLD); 2202*698f87a4SGarrett D'Amore term_word(p, link->string); 220395c635efSGarrett D'Amore term_fontpop(p); 220495c635efSGarrett D'Amore 220595c635efSGarrett D'Amore return(0); 220695c635efSGarrett D'Amore } 220795c635efSGarrett D'Amore 220895c635efSGarrett D'Amore 220995c635efSGarrett D'Amore /* ARGSUSED */ 221095c635efSGarrett D'Amore static int 221195c635efSGarrett D'Amore termp_bk_pre(DECL_ARGS) 221295c635efSGarrett D'Amore { 221395c635efSGarrett D'Amore 221495c635efSGarrett D'Amore switch (n->type) { 221595c635efSGarrett D'Amore case (MDOC_BLOCK): 221695c635efSGarrett D'Amore break; 221795c635efSGarrett D'Amore case (MDOC_HEAD): 221895c635efSGarrett D'Amore return(0); 221995c635efSGarrett D'Amore case (MDOC_BODY): 222095c635efSGarrett D'Amore if (n->parent->args || 0 == n->prev->nchild) 222195c635efSGarrett D'Amore p->flags |= TERMP_PREKEEP; 222295c635efSGarrett D'Amore break; 222395c635efSGarrett D'Amore default: 222495c635efSGarrett D'Amore abort(); 222595c635efSGarrett D'Amore /* NOTREACHED */ 222695c635efSGarrett D'Amore } 222795c635efSGarrett D'Amore 222895c635efSGarrett D'Amore return(1); 222995c635efSGarrett D'Amore } 223095c635efSGarrett D'Amore 223195c635efSGarrett D'Amore 223295c635efSGarrett D'Amore /* ARGSUSED */ 223395c635efSGarrett D'Amore static void 223495c635efSGarrett D'Amore termp_bk_post(DECL_ARGS) 223595c635efSGarrett D'Amore { 223695c635efSGarrett D'Amore 223795c635efSGarrett D'Amore if (MDOC_BODY == n->type) 223895c635efSGarrett D'Amore p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); 223995c635efSGarrett D'Amore } 224095c635efSGarrett D'Amore 224195c635efSGarrett D'Amore /* ARGSUSED */ 224295c635efSGarrett D'Amore static void 224395c635efSGarrett D'Amore termp__t_post(DECL_ARGS) 224495c635efSGarrett D'Amore { 224595c635efSGarrett D'Amore 224695c635efSGarrett D'Amore /* 224795c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote 224895c635efSGarrett D'Amore * us instead of underlining us (for disambiguation). 224995c635efSGarrett D'Amore */ 225095c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok && 225195c635efSGarrett D'Amore n->parent->norm->Rs.quote_T) 2252*698f87a4SGarrett D'Amore termp_quote_post(p, pair, meta, n); 225395c635efSGarrett D'Amore 2254*698f87a4SGarrett D'Amore termp____post(p, pair, meta, n); 225595c635efSGarrett D'Amore } 225695c635efSGarrett D'Amore 225795c635efSGarrett D'Amore /* ARGSUSED */ 225895c635efSGarrett D'Amore static int 225995c635efSGarrett D'Amore termp__t_pre(DECL_ARGS) 226095c635efSGarrett D'Amore { 226195c635efSGarrett D'Amore 226295c635efSGarrett D'Amore /* 226395c635efSGarrett D'Amore * If we're in an `Rs' and there's a journal present, then quote 226495c635efSGarrett D'Amore * us instead of underlining us (for disambiguation). 226595c635efSGarrett D'Amore */ 226695c635efSGarrett D'Amore if (n->parent && MDOC_Rs == n->parent->tok && 226795c635efSGarrett D'Amore n->parent->norm->Rs.quote_T) 2268*698f87a4SGarrett D'Amore return(termp_quote_pre(p, pair, meta, n)); 226995c635efSGarrett D'Amore 227095c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 227195c635efSGarrett D'Amore return(1); 227295c635efSGarrett D'Amore } 227395c635efSGarrett D'Amore 227495c635efSGarrett D'Amore /* ARGSUSED */ 227595c635efSGarrett D'Amore static int 227695c635efSGarrett D'Amore termp_under_pre(DECL_ARGS) 227795c635efSGarrett D'Amore { 227895c635efSGarrett D'Amore 227995c635efSGarrett D'Amore term_fontpush(p, TERMFONT_UNDER); 228095c635efSGarrett D'Amore return(1); 228195c635efSGarrett D'Amore } 2282