1*99db7d0eSSascha Wildner /* $Id: mdoc_html.c,v 1.342 2021/03/30 19:26:20 schwarze Exp $ */
280387638SSascha Wildner /*
3*99db7d0eSSascha Wildner * Copyright (c) 2014-2021 Ingo Schwarze <schwarze@openbsd.org>
454ba9607SSascha Wildner * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
580387638SSascha Wildner *
680387638SSascha Wildner * Permission to use, copy, modify, and distribute this software for any
780387638SSascha Wildner * purpose with or without fee is hereby granted, provided that the above
880387638SSascha Wildner * copyright notice and this permission notice appear in all copies.
980387638SSascha Wildner *
1054ba9607SSascha Wildner * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
1180387638SSascha Wildner * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1254ba9607SSascha Wildner * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
1380387638SSascha Wildner * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1480387638SSascha Wildner * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1580387638SSascha Wildner * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1680387638SSascha Wildner * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*99db7d0eSSascha Wildner *
18*99db7d0eSSascha Wildner * HTML formatter for mdoc(7) used by mandoc(1).
1980387638SSascha Wildner */
2080387638SSascha Wildner #include "config.h"
2180387638SSascha Wildner
2280387638SSascha Wildner #include <sys/types.h>
2380387638SSascha Wildner
2480387638SSascha Wildner #include <assert.h>
2580387638SSascha Wildner #include <ctype.h>
2680387638SSascha Wildner #include <stdio.h>
2780387638SSascha Wildner #include <stdlib.h>
2880387638SSascha Wildner #include <string.h>
2980387638SSascha Wildner #include <unistd.h>
3080387638SSascha Wildner
31070c62a6SFranco Fichtner #include "mandoc_aux.h"
3254ba9607SSascha Wildner #include "mandoc.h"
3354ba9607SSascha Wildner #include "roff.h"
3454ba9607SSascha Wildner #include "mdoc.h"
3580387638SSascha Wildner #include "out.h"
3680387638SSascha Wildner #include "html.h"
3780387638SSascha Wildner #include "main.h"
3880387638SSascha Wildner
3954ba9607SSascha Wildner #define MDOC_ARGS const struct roff_meta *meta, \
4054ba9607SSascha Wildner struct roff_node *n, \
4180387638SSascha Wildner struct html *h
4280387638SSascha Wildner
4380387638SSascha Wildner #ifndef MIN
4480387638SSascha Wildner #define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
4580387638SSascha Wildner #endif
4680387638SSascha Wildner
4754ba9607SSascha Wildner struct mdoc_html_act {
4880387638SSascha Wildner int (*pre)(MDOC_ARGS);
4980387638SSascha Wildner void (*post)(MDOC_ARGS);
5080387638SSascha Wildner };
5180387638SSascha Wildner
5254ba9607SSascha Wildner static void print_mdoc_head(const struct roff_meta *,
5354ba9607SSascha Wildner struct html *);
5480387638SSascha Wildner static void print_mdoc_node(MDOC_ARGS);
5580387638SSascha Wildner static void print_mdoc_nodelist(MDOC_ARGS);
56*99db7d0eSSascha Wildner static void synopsis_pre(struct html *, struct roff_node *);
5780387638SSascha Wildner
5854ba9607SSascha Wildner static void mdoc_root_post(const struct roff_meta *,
5954ba9607SSascha Wildner struct html *);
6054ba9607SSascha Wildner static int mdoc_root_pre(const struct roff_meta *,
6154ba9607SSascha Wildner struct html *);
6280387638SSascha Wildner
6380387638SSascha Wildner static void mdoc__x_post(MDOC_ARGS);
6480387638SSascha Wildner static int mdoc__x_pre(MDOC_ARGS);
6554ba9607SSascha Wildner static int mdoc_abort_pre(MDOC_ARGS);
6680387638SSascha Wildner static int mdoc_ad_pre(MDOC_ARGS);
6780387638SSascha Wildner static int mdoc_an_pre(MDOC_ARGS);
6880387638SSascha Wildner static int mdoc_ap_pre(MDOC_ARGS);
6980387638SSascha Wildner static int mdoc_ar_pre(MDOC_ARGS);
7080387638SSascha Wildner static int mdoc_bd_pre(MDOC_ARGS);
7180387638SSascha Wildner static int mdoc_bf_pre(MDOC_ARGS);
7280387638SSascha Wildner static void mdoc_bk_post(MDOC_ARGS);
7380387638SSascha Wildner static int mdoc_bk_pre(MDOC_ARGS);
7480387638SSascha Wildner static int mdoc_bl_pre(MDOC_ARGS);
7580387638SSascha Wildner static int mdoc_cd_pre(MDOC_ARGS);
76*99db7d0eSSascha Wildner static int mdoc_code_pre(MDOC_ARGS);
7780387638SSascha Wildner static int mdoc_d1_pre(MDOC_ARGS);
7880387638SSascha Wildner static int mdoc_fa_pre(MDOC_ARGS);
7980387638SSascha Wildner static int mdoc_fd_pre(MDOC_ARGS);
8080387638SSascha Wildner static int mdoc_fl_pre(MDOC_ARGS);
8180387638SSascha Wildner static int mdoc_fn_pre(MDOC_ARGS);
8280387638SSascha Wildner static int mdoc_ft_pre(MDOC_ARGS);
8380387638SSascha Wildner static int mdoc_em_pre(MDOC_ARGS);
8454ba9607SSascha Wildner static void mdoc_eo_post(MDOC_ARGS);
8554ba9607SSascha Wildner static int mdoc_eo_pre(MDOC_ARGS);
8680387638SSascha Wildner static int mdoc_ex_pre(MDOC_ARGS);
8780387638SSascha Wildner static void mdoc_fo_post(MDOC_ARGS);
8880387638SSascha Wildner static int mdoc_fo_pre(MDOC_ARGS);
8980387638SSascha Wildner static int mdoc_igndelim_pre(MDOC_ARGS);
9080387638SSascha Wildner static int mdoc_in_pre(MDOC_ARGS);
9180387638SSascha Wildner static int mdoc_it_pre(MDOC_ARGS);
9280387638SSascha Wildner static int mdoc_lb_pre(MDOC_ARGS);
9380387638SSascha Wildner static int mdoc_lk_pre(MDOC_ARGS);
9480387638SSascha Wildner static int mdoc_mt_pre(MDOC_ARGS);
9580387638SSascha Wildner static int mdoc_nd_pre(MDOC_ARGS);
9680387638SSascha Wildner static int mdoc_nm_pre(MDOC_ARGS);
9754ba9607SSascha Wildner static int mdoc_no_pre(MDOC_ARGS);
9880387638SSascha Wildner static int mdoc_ns_pre(MDOC_ARGS);
9980387638SSascha Wildner static int mdoc_pa_pre(MDOC_ARGS);
10080387638SSascha Wildner static void mdoc_pf_post(MDOC_ARGS);
10180387638SSascha Wildner static int mdoc_pp_pre(MDOC_ARGS);
10280387638SSascha Wildner static void mdoc_quote_post(MDOC_ARGS);
10380387638SSascha Wildner static int mdoc_quote_pre(MDOC_ARGS);
10480387638SSascha Wildner static int mdoc_rs_pre(MDOC_ARGS);
10580387638SSascha Wildner static int mdoc_sh_pre(MDOC_ARGS);
106070c62a6SFranco Fichtner static int mdoc_skip_pre(MDOC_ARGS);
10780387638SSascha Wildner static int mdoc_sm_pre(MDOC_ARGS);
10880387638SSascha Wildner static int mdoc_ss_pre(MDOC_ARGS);
10954ba9607SSascha Wildner static int mdoc_st_pre(MDOC_ARGS);
11080387638SSascha Wildner static int mdoc_sx_pre(MDOC_ARGS);
11180387638SSascha Wildner static int mdoc_sy_pre(MDOC_ARGS);
112*99db7d0eSSascha Wildner static int mdoc_tg_pre(MDOC_ARGS);
11380387638SSascha Wildner static int mdoc_va_pre(MDOC_ARGS);
11480387638SSascha Wildner static int mdoc_vt_pre(MDOC_ARGS);
11580387638SSascha Wildner static int mdoc_xr_pre(MDOC_ARGS);
11680387638SSascha Wildner static int mdoc_xx_pre(MDOC_ARGS);
11780387638SSascha Wildner
11854ba9607SSascha Wildner static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = {
11980387638SSascha Wildner {NULL, NULL}, /* Dd */
12080387638SSascha Wildner {NULL, NULL}, /* Dt */
12180387638SSascha Wildner {NULL, NULL}, /* Os */
12280387638SSascha Wildner {mdoc_sh_pre, NULL }, /* Sh */
12380387638SSascha Wildner {mdoc_ss_pre, NULL }, /* Ss */
12480387638SSascha Wildner {mdoc_pp_pre, NULL}, /* Pp */
12580387638SSascha Wildner {mdoc_d1_pre, NULL}, /* D1 */
12680387638SSascha Wildner {mdoc_d1_pre, NULL}, /* Dl */
12780387638SSascha Wildner {mdoc_bd_pre, NULL}, /* Bd */
12880387638SSascha Wildner {NULL, NULL}, /* Ed */
12980387638SSascha Wildner {mdoc_bl_pre, NULL}, /* Bl */
13080387638SSascha Wildner {NULL, NULL}, /* El */
13180387638SSascha Wildner {mdoc_it_pre, NULL}, /* It */
13280387638SSascha Wildner {mdoc_ad_pre, NULL}, /* Ad */
13380387638SSascha Wildner {mdoc_an_pre, NULL}, /* An */
13454ba9607SSascha Wildner {mdoc_ap_pre, NULL}, /* Ap */
13580387638SSascha Wildner {mdoc_ar_pre, NULL}, /* Ar */
13680387638SSascha Wildner {mdoc_cd_pre, NULL}, /* Cd */
137*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Cm */
138*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Dv */
139*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Er */
140*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Ev */
14180387638SSascha Wildner {mdoc_ex_pre, NULL}, /* Ex */
14280387638SSascha Wildner {mdoc_fa_pre, NULL}, /* Fa */
14380387638SSascha Wildner {mdoc_fd_pre, NULL}, /* Fd */
14480387638SSascha Wildner {mdoc_fl_pre, NULL}, /* Fl */
14580387638SSascha Wildner {mdoc_fn_pre, NULL}, /* Fn */
14680387638SSascha Wildner {mdoc_ft_pre, NULL}, /* Ft */
147*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Ic */
14880387638SSascha Wildner {mdoc_in_pre, NULL}, /* In */
149*99db7d0eSSascha Wildner {mdoc_code_pre, NULL}, /* Li */
15080387638SSascha Wildner {mdoc_nd_pre, NULL}, /* Nd */
15180387638SSascha Wildner {mdoc_nm_pre, NULL}, /* Nm */
15280387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Op */
15354ba9607SSascha Wildner {mdoc_abort_pre, NULL}, /* Ot */
15480387638SSascha Wildner {mdoc_pa_pre, NULL}, /* Pa */
15554ba9607SSascha Wildner {mdoc_ex_pre, NULL}, /* Rv */
15654ba9607SSascha Wildner {mdoc_st_pre, NULL}, /* St */
15780387638SSascha Wildner {mdoc_va_pre, NULL}, /* Va */
15880387638SSascha Wildner {mdoc_vt_pre, NULL}, /* Vt */
15980387638SSascha Wildner {mdoc_xr_pre, NULL}, /* Xr */
16080387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %A */
16180387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %B */
16280387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %D */
16380387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %I */
16480387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %J */
16580387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %N */
16680387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %O */
16780387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %P */
16880387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %R */
16980387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %T */
17080387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %V */
17180387638SSascha Wildner {NULL, NULL}, /* Ac */
17280387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Ao */
17380387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Aq */
17454ba9607SSascha Wildner {mdoc_xx_pre, NULL}, /* At */
17580387638SSascha Wildner {NULL, NULL}, /* Bc */
17680387638SSascha Wildner {mdoc_bf_pre, NULL}, /* Bf */
17780387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Bo */
17880387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Bq */
17980387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Bsx */
18054ba9607SSascha Wildner {mdoc_xx_pre, NULL}, /* Bx */
18154ba9607SSascha Wildner {mdoc_skip_pre, NULL}, /* Db */
18280387638SSascha Wildner {NULL, NULL}, /* Dc */
18380387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Do */
18480387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Dq */
18580387638SSascha Wildner {NULL, NULL}, /* Ec */ /* FIXME: no space */
18680387638SSascha Wildner {NULL, NULL}, /* Ef */
18780387638SSascha Wildner {mdoc_em_pre, NULL}, /* Em */
18854ba9607SSascha Wildner {mdoc_eo_pre, mdoc_eo_post}, /* Eo */
18980387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Fx */
190*99db7d0eSSascha Wildner {mdoc_no_pre, NULL}, /* Ms */
19154ba9607SSascha Wildner {mdoc_no_pre, NULL}, /* No */
19280387638SSascha Wildner {mdoc_ns_pre, NULL}, /* Ns */
19380387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Nx */
19480387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Ox */
19580387638SSascha Wildner {NULL, NULL}, /* Pc */
19680387638SSascha Wildner {mdoc_igndelim_pre, mdoc_pf_post}, /* Pf */
19780387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Po */
19880387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Pq */
19980387638SSascha Wildner {NULL, NULL}, /* Qc */
20080387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Ql */
20180387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Qo */
20280387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Qq */
20380387638SSascha Wildner {NULL, NULL}, /* Re */
20480387638SSascha Wildner {mdoc_rs_pre, NULL}, /* Rs */
20580387638SSascha Wildner {NULL, NULL}, /* Sc */
20680387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* So */
20780387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Sq */
20880387638SSascha Wildner {mdoc_sm_pre, NULL}, /* Sm */
20980387638SSascha Wildner {mdoc_sx_pre, NULL}, /* Sx */
21080387638SSascha Wildner {mdoc_sy_pre, NULL}, /* Sy */
21180387638SSascha Wildner {NULL, NULL}, /* Tn */
21280387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Ux */
21380387638SSascha Wildner {NULL, NULL}, /* Xc */
21480387638SSascha Wildner {NULL, NULL}, /* Xo */
21580387638SSascha Wildner {mdoc_fo_pre, mdoc_fo_post}, /* Fo */
21680387638SSascha Wildner {NULL, NULL}, /* Fc */
21780387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Oo */
21880387638SSascha Wildner {NULL, NULL}, /* Oc */
21980387638SSascha Wildner {mdoc_bk_pre, mdoc_bk_post}, /* Bk */
22080387638SSascha Wildner {NULL, NULL}, /* Ek */
22154ba9607SSascha Wildner {NULL, NULL}, /* Bt */
22280387638SSascha Wildner {NULL, NULL}, /* Hf */
223070c62a6SFranco Fichtner {mdoc_em_pre, NULL}, /* Fr */
22454ba9607SSascha Wildner {NULL, NULL}, /* Ud */
22580387638SSascha Wildner {mdoc_lb_pre, NULL}, /* Lb */
22654ba9607SSascha Wildner {mdoc_abort_pre, NULL}, /* Lp */
22780387638SSascha Wildner {mdoc_lk_pre, NULL}, /* Lk */
22880387638SSascha Wildner {mdoc_mt_pre, NULL}, /* Mt */
22980387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Brq */
23080387638SSascha Wildner {mdoc_quote_pre, mdoc_quote_post}, /* Bro */
23180387638SSascha Wildner {NULL, NULL}, /* Brc */
23280387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %C */
233070c62a6SFranco Fichtner {mdoc_skip_pre, NULL}, /* Es */
234070c62a6SFranco Fichtner {mdoc_quote_pre, mdoc_quote_post}, /* En */
23580387638SSascha Wildner {mdoc_xx_pre, NULL}, /* Dx */
23680387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %Q */
23780387638SSascha Wildner {mdoc__x_pre, mdoc__x_post}, /* %U */
23880387638SSascha Wildner {NULL, NULL}, /* Ta */
239*99db7d0eSSascha Wildner {mdoc_tg_pre, NULL}, /* Tg */
24080387638SSascha Wildner };
24180387638SSascha Wildner
24280387638SSascha Wildner
24380387638SSascha Wildner /*
24480387638SSascha Wildner * See the same function in mdoc_term.c for documentation.
24580387638SSascha Wildner */
24680387638SSascha Wildner static void
synopsis_pre(struct html * h,struct roff_node * n)247*99db7d0eSSascha Wildner synopsis_pre(struct html *h, struct roff_node *n)
24880387638SSascha Wildner {
249*99db7d0eSSascha Wildner struct roff_node *np;
25080387638SSascha Wildner
251*99db7d0eSSascha Wildner if ((n->flags & NODE_SYNPRETTY) == 0 ||
252*99db7d0eSSascha Wildner (np = roff_node_prev(n)) == NULL)
25380387638SSascha Wildner return;
25480387638SSascha Wildner
255*99db7d0eSSascha Wildner if (np->tok == n->tok &&
25680387638SSascha Wildner MDOC_Fo != n->tok &&
25780387638SSascha Wildner MDOC_Ft != n->tok &&
25880387638SSascha Wildner MDOC_Fn != n->tok) {
25954ba9607SSascha Wildner print_otag(h, TAG_BR, "");
26080387638SSascha Wildner return;
26180387638SSascha Wildner }
26280387638SSascha Wildner
263*99db7d0eSSascha Wildner switch (np->tok) {
264070c62a6SFranco Fichtner case MDOC_Fd:
265070c62a6SFranco Fichtner case MDOC_Fn:
266070c62a6SFranco Fichtner case MDOC_Fo:
267070c62a6SFranco Fichtner case MDOC_In:
268070c62a6SFranco Fichtner case MDOC_Vt:
26980387638SSascha Wildner break;
270070c62a6SFranco Fichtner case MDOC_Ft:
27154ba9607SSascha Wildner if (n->tok != MDOC_Fn && n->tok != MDOC_Fo)
27280387638SSascha Wildner break;
27380387638SSascha Wildner /* FALLTHROUGH */
27480387638SSascha Wildner default:
27554ba9607SSascha Wildner print_otag(h, TAG_BR, "");
27654ba9607SSascha Wildner return;
27780387638SSascha Wildner }
27854ba9607SSascha Wildner html_close_paragraph(h);
27954ba9607SSascha Wildner print_otag(h, TAG_P, "c", "Pp");
28080387638SSascha Wildner }
28180387638SSascha Wildner
28254ba9607SSascha Wildner void
html_mdoc(void * arg,const struct roff_meta * mdoc)28354ba9607SSascha Wildner html_mdoc(void *arg, const struct roff_meta *mdoc)
28480387638SSascha Wildner {
28554ba9607SSascha Wildner struct html *h;
28654ba9607SSascha Wildner struct roff_node *n;
28754ba9607SSascha Wildner struct tag *t;
28880387638SSascha Wildner
28954ba9607SSascha Wildner h = (struct html *)arg;
29054ba9607SSascha Wildner n = mdoc->first->child;
29180387638SSascha Wildner
29254ba9607SSascha Wildner if ((h->oflags & HTML_FRAGMENT) == 0) {
29336342e81SSascha Wildner print_gen_decls(h);
29454ba9607SSascha Wildner print_otag(h, TAG_HTML, "");
29554ba9607SSascha Wildner if (n != NULL && n->type == ROFFT_COMMENT)
29654ba9607SSascha Wildner print_gen_comment(h, n);
29754ba9607SSascha Wildner t = print_otag(h, TAG_HEAD, "");
29854ba9607SSascha Wildner print_mdoc_head(mdoc, h);
29980387638SSascha Wildner print_tagq(h, t);
30054ba9607SSascha Wildner print_otag(h, TAG_BODY, "");
30154ba9607SSascha Wildner }
30254ba9607SSascha Wildner
30354ba9607SSascha Wildner mdoc_root_pre(mdoc, h);
30454ba9607SSascha Wildner t = print_otag(h, TAG_DIV, "c", "manual-text");
30554ba9607SSascha Wildner print_mdoc_nodelist(mdoc, n, h);
30654ba9607SSascha Wildner print_tagq(h, t);
30754ba9607SSascha Wildner mdoc_root_post(mdoc, h);
30854ba9607SSascha Wildner print_tagq(h, NULL);
30980387638SSascha Wildner }
31080387638SSascha Wildner
31180387638SSascha Wildner static void
print_mdoc_head(const struct roff_meta * meta,struct html * h)31254ba9607SSascha Wildner print_mdoc_head(const struct roff_meta *meta, struct html *h)
31380387638SSascha Wildner {
31454ba9607SSascha Wildner char *cp;
31580387638SSascha Wildner
31680387638SSascha Wildner print_gen_head(h);
31780387638SSascha Wildner
31854ba9607SSascha Wildner if (meta->arch != NULL && meta->msec != NULL)
31954ba9607SSascha Wildner mandoc_asprintf(&cp, "%s(%s) (%s)", meta->title,
32054ba9607SSascha Wildner meta->msec, meta->arch);
32154ba9607SSascha Wildner else if (meta->msec != NULL)
32254ba9607SSascha Wildner mandoc_asprintf(&cp, "%s(%s)", meta->title, meta->msec);
32354ba9607SSascha Wildner else if (meta->arch != NULL)
32454ba9607SSascha Wildner mandoc_asprintf(&cp, "%s (%s)", meta->title, meta->arch);
32554ba9607SSascha Wildner else
32654ba9607SSascha Wildner cp = mandoc_strdup(meta->title);
32754ba9607SSascha Wildner
32854ba9607SSascha Wildner print_otag(h, TAG_TITLE, "");
32954ba9607SSascha Wildner print_text(h, cp);
33054ba9607SSascha Wildner free(cp);
33180387638SSascha Wildner }
33280387638SSascha Wildner
33380387638SSascha Wildner static void
print_mdoc_nodelist(MDOC_ARGS)33480387638SSascha Wildner print_mdoc_nodelist(MDOC_ARGS)
33580387638SSascha Wildner {
33680387638SSascha Wildner
33754ba9607SSascha Wildner while (n != NULL) {
338f88b6c16SFranco Fichtner print_mdoc_node(meta, n, h);
33954ba9607SSascha Wildner n = n->next;
34054ba9607SSascha Wildner }
34180387638SSascha Wildner }
34280387638SSascha Wildner
34380387638SSascha Wildner static void
print_mdoc_node(MDOC_ARGS)34480387638SSascha Wildner print_mdoc_node(MDOC_ARGS)
34580387638SSascha Wildner {
34680387638SSascha Wildner struct tag *t;
34754ba9607SSascha Wildner int child;
34854ba9607SSascha Wildner
34954ba9607SSascha Wildner if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
35054ba9607SSascha Wildner return;
35154ba9607SSascha Wildner
352*99db7d0eSSascha Wildner if ((n->flags & NODE_NOFILL) == 0)
353*99db7d0eSSascha Wildner html_fillmode(h, ROFF_fi);
354*99db7d0eSSascha Wildner else if (html_fillmode(h, ROFF_nf) == ROFF_nf &&
355*99db7d0eSSascha Wildner n->tok != ROFF_fi && n->flags & NODE_LINE)
356*99db7d0eSSascha Wildner print_endline(h);
35780387638SSascha Wildner
35880387638SSascha Wildner child = 1;
35954ba9607SSascha Wildner n->flags &= ~NODE_ENDED;
36080387638SSascha Wildner switch (n->type) {
36154ba9607SSascha Wildner case ROFFT_TEXT:
362*99db7d0eSSascha Wildner if (n->flags & NODE_LINE) {
363*99db7d0eSSascha Wildner switch (*n->string) {
364*99db7d0eSSascha Wildner case '\0':
365*99db7d0eSSascha Wildner h->col = 1;
366*99db7d0eSSascha Wildner print_endline(h);
367*99db7d0eSSascha Wildner return;
368*99db7d0eSSascha Wildner case ' ':
369*99db7d0eSSascha Wildner if ((h->flags & HTML_NONEWLINE) == 0 &&
37054ba9607SSascha Wildner (n->flags & NODE_NOFILL) == 0)
37154ba9607SSascha Wildner print_otag(h, TAG_BR, "");
372*99db7d0eSSascha Wildner break;
373*99db7d0eSSascha Wildner default:
374*99db7d0eSSascha Wildner break;
375*99db7d0eSSascha Wildner }
376*99db7d0eSSascha Wildner }
377*99db7d0eSSascha Wildner t = h->tag;
378*99db7d0eSSascha Wildner t->refcnt++;
379*99db7d0eSSascha Wildner if (n->flags & NODE_DELIMC)
38060e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
381*99db7d0eSSascha Wildner if (n->flags & NODE_HREF)
382*99db7d0eSSascha Wildner print_tagged_text(h, n->string, n);
383*99db7d0eSSascha Wildner else
38480387638SSascha Wildner print_text(h, n->string);
385*99db7d0eSSascha Wildner if (n->flags & NODE_DELIMO)
38660e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
38754ba9607SSascha Wildner break;
38854ba9607SSascha Wildner case ROFFT_EQN:
38954ba9607SSascha Wildner t = h->tag;
39054ba9607SSascha Wildner t->refcnt++;
39136342e81SSascha Wildner print_eqn(h, n->eqn);
39280387638SSascha Wildner break;
39354ba9607SSascha Wildner case ROFFT_TBL:
39460e1e752SSascha Wildner /*
39560e1e752SSascha Wildner * This will take care of initialising all of the table
39660e1e752SSascha Wildner * state data for the first table, then tearing it down
39760e1e752SSascha Wildner * for the last one.
39860e1e752SSascha Wildner */
39960e1e752SSascha Wildner print_tbl(h, n->span);
40060e1e752SSascha Wildner return;
40180387638SSascha Wildner default:
40260e1e752SSascha Wildner /*
40360e1e752SSascha Wildner * Close out the current table, if it's open, and unset
40460e1e752SSascha Wildner * the "meta" table state. This will be reopened on the
40560e1e752SSascha Wildner * next table element.
40660e1e752SSascha Wildner */
40754ba9607SSascha Wildner if (h->tblt != NULL)
40860e1e752SSascha Wildner print_tblclose(h);
40954ba9607SSascha Wildner assert(h->tblt == NULL);
41054ba9607SSascha Wildner t = h->tag;
41154ba9607SSascha Wildner t->refcnt++;
41254ba9607SSascha Wildner if (n->tok < ROFF_MAX) {
41354ba9607SSascha Wildner roff_html_pre(h, n);
41454ba9607SSascha Wildner t->refcnt--;
41554ba9607SSascha Wildner print_stagq(h, t);
41654ba9607SSascha Wildner return;
41760e1e752SSascha Wildner }
41854ba9607SSascha Wildner assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
41954ba9607SSascha Wildner if (mdoc_html_acts[n->tok - MDOC_Dd].pre != NULL &&
42054ba9607SSascha Wildner (n->end == ENDBODY_NOT || n->child != NULL))
42154ba9607SSascha Wildner child = (*mdoc_html_acts[n->tok - MDOC_Dd].pre)(meta,
42254ba9607SSascha Wildner n, h);
42380387638SSascha Wildner break;
42480387638SSascha Wildner }
42580387638SSascha Wildner
42654ba9607SSascha Wildner if (h->flags & HTML_KEEP && n->flags & NODE_LINE) {
42780387638SSascha Wildner h->flags &= ~HTML_KEEP;
42880387638SSascha Wildner h->flags |= HTML_PREKEEP;
42980387638SSascha Wildner }
43080387638SSascha Wildner
43154ba9607SSascha Wildner if (child && n->child != NULL)
432f88b6c16SFranco Fichtner print_mdoc_nodelist(meta, n->child, h);
43380387638SSascha Wildner
43454ba9607SSascha Wildner t->refcnt--;
43580387638SSascha Wildner print_stagq(h, t);
43680387638SSascha Wildner
43780387638SSascha Wildner switch (n->type) {
43854ba9607SSascha Wildner case ROFFT_TEXT:
43954ba9607SSascha Wildner case ROFFT_EQN:
44080387638SSascha Wildner break;
44180387638SSascha Wildner default:
44254ba9607SSascha Wildner if (mdoc_html_acts[n->tok - MDOC_Dd].post == NULL ||
44354ba9607SSascha Wildner n->flags & NODE_ENDED)
44480387638SSascha Wildner break;
44554ba9607SSascha Wildner (*mdoc_html_acts[n->tok - MDOC_Dd].post)(meta, n, h);
44654ba9607SSascha Wildner if (n->end != ENDBODY_NOT)
44754ba9607SSascha Wildner n->body->flags |= NODE_ENDED;
44854ba9607SSascha Wildner break;
44954ba9607SSascha Wildner }
45080387638SSascha Wildner }
45180387638SSascha Wildner
45280387638SSascha Wildner static void
mdoc_root_post(const struct roff_meta * meta,struct html * h)45354ba9607SSascha Wildner mdoc_root_post(const struct roff_meta *meta, struct html *h)
45480387638SSascha Wildner {
45580387638SSascha Wildner struct tag *t, *tt;
45680387638SSascha Wildner
45754ba9607SSascha Wildner t = print_otag(h, TAG_TABLE, "c", "foot");
45854ba9607SSascha Wildner tt = print_otag(h, TAG_TR, "");
45980387638SSascha Wildner
46054ba9607SSascha Wildner print_otag(h, TAG_TD, "c", "foot-date");
461f88b6c16SFranco Fichtner print_text(h, meta->date);
46280387638SSascha Wildner print_stagq(h, tt);
46380387638SSascha Wildner
46454ba9607SSascha Wildner print_otag(h, TAG_TD, "c", "foot-os");
465f88b6c16SFranco Fichtner print_text(h, meta->os);
46680387638SSascha Wildner print_tagq(h, t);
46780387638SSascha Wildner }
46880387638SSascha Wildner
46980387638SSascha Wildner static int
mdoc_root_pre(const struct roff_meta * meta,struct html * h)47054ba9607SSascha Wildner mdoc_root_pre(const struct roff_meta *meta, struct html *h)
47180387638SSascha Wildner {
47280387638SSascha Wildner struct tag *t, *tt;
473070c62a6SFranco Fichtner char *volume, *title;
47480387638SSascha Wildner
475070c62a6SFranco Fichtner if (NULL == meta->arch)
476070c62a6SFranco Fichtner volume = mandoc_strdup(meta->vol);
477070c62a6SFranco Fichtner else
478070c62a6SFranco Fichtner mandoc_asprintf(&volume, "%s (%s)",
479070c62a6SFranco Fichtner meta->vol, meta->arch);
48080387638SSascha Wildner
481070c62a6SFranco Fichtner if (NULL == meta->msec)
482070c62a6SFranco Fichtner title = mandoc_strdup(meta->title);
483070c62a6SFranco Fichtner else
484070c62a6SFranco Fichtner mandoc_asprintf(&title, "%s(%s)",
485070c62a6SFranco Fichtner meta->title, meta->msec);
48680387638SSascha Wildner
48754ba9607SSascha Wildner t = print_otag(h, TAG_TABLE, "c", "head");
48854ba9607SSascha Wildner tt = print_otag(h, TAG_TR, "");
48980387638SSascha Wildner
49054ba9607SSascha Wildner print_otag(h, TAG_TD, "c", "head-ltitle");
49180387638SSascha Wildner print_text(h, title);
49280387638SSascha Wildner print_stagq(h, tt);
49380387638SSascha Wildner
49454ba9607SSascha Wildner print_otag(h, TAG_TD, "c", "head-vol");
495070c62a6SFranco Fichtner print_text(h, volume);
49680387638SSascha Wildner print_stagq(h, tt);
49780387638SSascha Wildner
49854ba9607SSascha Wildner print_otag(h, TAG_TD, "c", "head-rtitle");
49980387638SSascha Wildner print_text(h, title);
50080387638SSascha Wildner print_tagq(h, t);
501070c62a6SFranco Fichtner
502070c62a6SFranco Fichtner free(title);
503070c62a6SFranco Fichtner free(volume);
50454ba9607SSascha Wildner return 1;
50554ba9607SSascha Wildner }
50654ba9607SSascha Wildner
507*99db7d0eSSascha Wildner static int
mdoc_code_pre(MDOC_ARGS)508*99db7d0eSSascha Wildner mdoc_code_pre(MDOC_ARGS)
50954ba9607SSascha Wildner {
510*99db7d0eSSascha Wildner print_otag_id(h, TAG_CODE, roff_name[n->tok], n);
511*99db7d0eSSascha Wildner return 1;
51280387638SSascha Wildner }
51380387638SSascha Wildner
51480387638SSascha Wildner static int
mdoc_sh_pre(MDOC_ARGS)51580387638SSascha Wildner mdoc_sh_pre(MDOC_ARGS)
51680387638SSascha Wildner {
51754ba9607SSascha Wildner struct roff_node *sn, *subn;
51854ba9607SSascha Wildner struct tag *t, *tsec, *tsub;
51954ba9607SSascha Wildner char *id;
52054ba9607SSascha Wildner int sc;
52180387638SSascha Wildner
52254ba9607SSascha Wildner switch (n->type) {
52354ba9607SSascha Wildner case ROFFT_BLOCK:
52454ba9607SSascha Wildner html_close_paragraph(h);
52554ba9607SSascha Wildner if ((h->oflags & HTML_TOC) == 0 ||
52654ba9607SSascha Wildner h->flags & HTML_TOCDONE ||
52754ba9607SSascha Wildner n->sec <= SEC_SYNOPSIS) {
52854ba9607SSascha Wildner print_otag(h, TAG_SECTION, "c", "Sh");
52954ba9607SSascha Wildner break;
53080387638SSascha Wildner }
53154ba9607SSascha Wildner h->flags |= HTML_TOCDONE;
53254ba9607SSascha Wildner sc = 0;
53354ba9607SSascha Wildner for (sn = n->next; sn != NULL; sn = sn->next)
53454ba9607SSascha Wildner if (sn->sec == SEC_CUSTOM)
53554ba9607SSascha Wildner if (++sc == 2)
53654ba9607SSascha Wildner break;
53754ba9607SSascha Wildner if (sc < 2)
53854ba9607SSascha Wildner break;
53954ba9607SSascha Wildner t = print_otag(h, TAG_H1, "c", "Sh");
54054ba9607SSascha Wildner print_text(h, "TABLE OF CONTENTS");
54154ba9607SSascha Wildner print_tagq(h, t);
54254ba9607SSascha Wildner t = print_otag(h, TAG_UL, "c", "Bl-compact");
54354ba9607SSascha Wildner for (sn = n; sn != NULL; sn = sn->next) {
54454ba9607SSascha Wildner tsec = print_otag(h, TAG_LI, "");
54554ba9607SSascha Wildner id = html_make_id(sn->head, 0);
54654ba9607SSascha Wildner tsub = print_otag(h, TAG_A, "hR", id);
54754ba9607SSascha Wildner free(id);
54854ba9607SSascha Wildner print_mdoc_nodelist(meta, sn->head->child, h);
54954ba9607SSascha Wildner print_tagq(h, tsub);
55054ba9607SSascha Wildner tsub = NULL;
55154ba9607SSascha Wildner for (subn = sn->body->child; subn != NULL;
55254ba9607SSascha Wildner subn = subn->next) {
55354ba9607SSascha Wildner if (subn->tok != MDOC_Ss)
55454ba9607SSascha Wildner continue;
55554ba9607SSascha Wildner id = html_make_id(subn->head, 0);
55654ba9607SSascha Wildner if (id == NULL)
55754ba9607SSascha Wildner continue;
55854ba9607SSascha Wildner if (tsub == NULL)
55954ba9607SSascha Wildner print_otag(h, TAG_UL,
56054ba9607SSascha Wildner "c", "Bl-compact");
56154ba9607SSascha Wildner tsub = print_otag(h, TAG_LI, "");
56254ba9607SSascha Wildner print_otag(h, TAG_A, "hR", id);
56354ba9607SSascha Wildner free(id);
56454ba9607SSascha Wildner print_mdoc_nodelist(meta,
56554ba9607SSascha Wildner subn->head->child, h);
56654ba9607SSascha Wildner print_tagq(h, tsub);
56754ba9607SSascha Wildner }
56854ba9607SSascha Wildner print_tagq(h, tsec);
56954ba9607SSascha Wildner }
57054ba9607SSascha Wildner print_tagq(h, t);
57154ba9607SSascha Wildner print_otag(h, TAG_SECTION, "c", "Sh");
57254ba9607SSascha Wildner break;
57354ba9607SSascha Wildner case ROFFT_HEAD:
574*99db7d0eSSascha Wildner print_otag_id(h, TAG_H1, "Sh", n);
57554ba9607SSascha Wildner break;
57654ba9607SSascha Wildner case ROFFT_BODY:
57754ba9607SSascha Wildner if (n->sec == SEC_AUTHORS)
57854ba9607SSascha Wildner h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT);
57954ba9607SSascha Wildner break;
58054ba9607SSascha Wildner default:
58154ba9607SSascha Wildner break;
58254ba9607SSascha Wildner }
58354ba9607SSascha Wildner return 1;
58480387638SSascha Wildner }
58580387638SSascha Wildner
58680387638SSascha Wildner static int
mdoc_ss_pre(MDOC_ARGS)58780387638SSascha Wildner mdoc_ss_pre(MDOC_ARGS)
58880387638SSascha Wildner {
58954ba9607SSascha Wildner switch (n->type) {
59054ba9607SSascha Wildner case ROFFT_BLOCK:
59154ba9607SSascha Wildner html_close_paragraph(h);
59254ba9607SSascha Wildner print_otag(h, TAG_SECTION, "c", "Ss");
593*99db7d0eSSascha Wildner break;
59454ba9607SSascha Wildner case ROFFT_HEAD:
595*99db7d0eSSascha Wildner print_otag_id(h, TAG_H2, "Ss", n);
59654ba9607SSascha Wildner break;
59754ba9607SSascha Wildner case ROFFT_BODY:
598*99db7d0eSSascha Wildner break;
59954ba9607SSascha Wildner default:
60054ba9607SSascha Wildner abort();
60180387638SSascha Wildner }
60254ba9607SSascha Wildner return 1;
60380387638SSascha Wildner }
60480387638SSascha Wildner
60580387638SSascha Wildner static int
mdoc_fl_pre(MDOC_ARGS)60680387638SSascha Wildner mdoc_fl_pre(MDOC_ARGS)
60780387638SSascha Wildner {
608*99db7d0eSSascha Wildner struct roff_node *nn;
60980387638SSascha Wildner
610*99db7d0eSSascha Wildner print_otag_id(h, TAG_CODE, "Fl", n);
61180387638SSascha Wildner print_text(h, "\\-");
612*99db7d0eSSascha Wildner if (n->child != NULL ||
613*99db7d0eSSascha Wildner ((nn = roff_node_next(n)) != NULL &&
614*99db7d0eSSascha Wildner nn->type != ROFFT_TEXT &&
615*99db7d0eSSascha Wildner (nn->flags & NODE_LINE) == 0))
61680387638SSascha Wildner h->flags |= HTML_NOSPACE;
61780387638SSascha Wildner
61854ba9607SSascha Wildner return 1;
61954ba9607SSascha Wildner }
62054ba9607SSascha Wildner
62154ba9607SSascha Wildner static int
mdoc_nd_pre(MDOC_ARGS)62280387638SSascha Wildner mdoc_nd_pre(MDOC_ARGS)
62380387638SSascha Wildner {
62454ba9607SSascha Wildner switch (n->type) {
62554ba9607SSascha Wildner case ROFFT_BLOCK:
62654ba9607SSascha Wildner return 1;
62754ba9607SSascha Wildner case ROFFT_HEAD:
62854ba9607SSascha Wildner return 0;
62954ba9607SSascha Wildner case ROFFT_BODY:
63054ba9607SSascha Wildner break;
63154ba9607SSascha Wildner default:
63254ba9607SSascha Wildner abort();
63354ba9607SSascha Wildner }
63480387638SSascha Wildner print_text(h, "\\(em");
635*99db7d0eSSascha Wildner print_otag(h, TAG_SPAN, "c", "Nd");
63654ba9607SSascha Wildner return 1;
63780387638SSascha Wildner }
63880387638SSascha Wildner
63980387638SSascha Wildner static int
mdoc_nm_pre(MDOC_ARGS)64080387638SSascha Wildner mdoc_nm_pre(MDOC_ARGS)
64180387638SSascha Wildner {
64280387638SSascha Wildner switch (n->type) {
64354ba9607SSascha Wildner case ROFFT_BLOCK:
64480387638SSascha Wildner break;
64554ba9607SSascha Wildner case ROFFT_HEAD:
64654ba9607SSascha Wildner print_otag(h, TAG_TD, "");
64754ba9607SSascha Wildner /* FALLTHROUGH */
64854ba9607SSascha Wildner case ROFFT_ELEM:
64954ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "Nm");
65054ba9607SSascha Wildner return 1;
65154ba9607SSascha Wildner case ROFFT_BODY:
65254ba9607SSascha Wildner print_otag(h, TAG_TD, "");
65354ba9607SSascha Wildner return 1;
65454ba9607SSascha Wildner default:
65554ba9607SSascha Wildner abort();
65680387638SSascha Wildner }
65754ba9607SSascha Wildner html_close_paragraph(h);
65880387638SSascha Wildner synopsis_pre(h, n);
65954ba9607SSascha Wildner print_otag(h, TAG_TABLE, "c", "Nm");
66054ba9607SSascha Wildner print_otag(h, TAG_TR, "");
66154ba9607SSascha Wildner return 1;
66280387638SSascha Wildner }
66380387638SSascha Wildner
66480387638SSascha Wildner static int
mdoc_xr_pre(MDOC_ARGS)66580387638SSascha Wildner mdoc_xr_pre(MDOC_ARGS)
66680387638SSascha Wildner {
66780387638SSascha Wildner if (NULL == n->child)
66854ba9607SSascha Wildner return 0;
66980387638SSascha Wildner
67054ba9607SSascha Wildner if (h->base_man1)
67154ba9607SSascha Wildner print_otag(h, TAG_A, "chM", "Xr",
67254ba9607SSascha Wildner n->child->string, n->child->next == NULL ?
67354ba9607SSascha Wildner NULL : n->child->next->string);
67454ba9607SSascha Wildner else
67554ba9607SSascha Wildner print_otag(h, TAG_A, "c", "Xr");
67680387638SSascha Wildner
67760e1e752SSascha Wildner n = n->child;
67860e1e752SSascha Wildner print_text(h, n->string);
67980387638SSascha Wildner
68060e1e752SSascha Wildner if (NULL == (n = n->next))
68154ba9607SSascha Wildner return 0;
68280387638SSascha Wildner
68380387638SSascha Wildner h->flags |= HTML_NOSPACE;
68480387638SSascha Wildner print_text(h, "(");
68580387638SSascha Wildner h->flags |= HTML_NOSPACE;
68660e1e752SSascha Wildner print_text(h, n->string);
68780387638SSascha Wildner h->flags |= HTML_NOSPACE;
68880387638SSascha Wildner print_text(h, ")");
68954ba9607SSascha Wildner return 0;
69080387638SSascha Wildner }
69180387638SSascha Wildner
69280387638SSascha Wildner static int
mdoc_tg_pre(MDOC_ARGS)693*99db7d0eSSascha Wildner mdoc_tg_pre(MDOC_ARGS)
694*99db7d0eSSascha Wildner {
695*99db7d0eSSascha Wildner char *id;
696*99db7d0eSSascha Wildner
697*99db7d0eSSascha Wildner if ((id = html_make_id(n, 1)) != NULL) {
698*99db7d0eSSascha Wildner print_tagq(h, print_otag(h, TAG_MARK, "i", id));
699*99db7d0eSSascha Wildner free(id);
700*99db7d0eSSascha Wildner }
701*99db7d0eSSascha Wildner return 0;
702*99db7d0eSSascha Wildner }
703*99db7d0eSSascha Wildner
704*99db7d0eSSascha Wildner static int
mdoc_ns_pre(MDOC_ARGS)70580387638SSascha Wildner mdoc_ns_pre(MDOC_ARGS)
70680387638SSascha Wildner {
70780387638SSascha Wildner
70854ba9607SSascha Wildner if ( ! (NODE_LINE & n->flags))
70980387638SSascha Wildner h->flags |= HTML_NOSPACE;
71054ba9607SSascha Wildner return 1;
71180387638SSascha Wildner }
71280387638SSascha Wildner
71380387638SSascha Wildner static int
mdoc_ar_pre(MDOC_ARGS)71480387638SSascha Wildner mdoc_ar_pre(MDOC_ARGS)
71580387638SSascha Wildner {
71654ba9607SSascha Wildner print_otag(h, TAG_VAR, "c", "Ar");
71754ba9607SSascha Wildner return 1;
71880387638SSascha Wildner }
71980387638SSascha Wildner
72080387638SSascha Wildner static int
mdoc_xx_pre(MDOC_ARGS)72180387638SSascha Wildner mdoc_xx_pre(MDOC_ARGS)
72280387638SSascha Wildner {
72354ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "Ux");
72454ba9607SSascha Wildner return 1;
72580387638SSascha Wildner }
72680387638SSascha Wildner
72780387638SSascha Wildner static int
mdoc_it_pre(MDOC_ARGS)72880387638SSascha Wildner mdoc_it_pre(MDOC_ARGS)
72980387638SSascha Wildner {
73054ba9607SSascha Wildner const struct roff_node *bl;
73180387638SSascha Wildner enum mdoc_list type;
73280387638SSascha Wildner
73380387638SSascha Wildner bl = n->parent;
73454ba9607SSascha Wildner while (bl->tok != MDOC_Bl)
73580387638SSascha Wildner bl = bl->parent;
73680387638SSascha Wildner type = bl->norm->Bl.type;
73780387638SSascha Wildner
73880387638SSascha Wildner switch (type) {
739070c62a6SFranco Fichtner case LIST_bullet:
740070c62a6SFranco Fichtner case LIST_dash:
741070c62a6SFranco Fichtner case LIST_hyphen:
74254ba9607SSascha Wildner case LIST_item:
743070c62a6SFranco Fichtner case LIST_enum:
74454ba9607SSascha Wildner switch (n->type) {
74554ba9607SSascha Wildner case ROFFT_HEAD:
74654ba9607SSascha Wildner return 0;
74754ba9607SSascha Wildner case ROFFT_BODY:
748*99db7d0eSSascha Wildner print_otag_id(h, TAG_LI, NULL, n);
74980387638SSascha Wildner break;
75080387638SSascha Wildner default:
75180387638SSascha Wildner break;
75280387638SSascha Wildner }
75380387638SSascha Wildner break;
754070c62a6SFranco Fichtner case LIST_diag:
755070c62a6SFranco Fichtner case LIST_hang:
756070c62a6SFranco Fichtner case LIST_inset:
757070c62a6SFranco Fichtner case LIST_ohang:
75854ba9607SSascha Wildner switch (n->type) {
75954ba9607SSascha Wildner case ROFFT_HEAD:
760*99db7d0eSSascha Wildner print_otag_id(h, TAG_DT, NULL, n);
76154ba9607SSascha Wildner break;
76254ba9607SSascha Wildner case ROFFT_BODY:
76354ba9607SSascha Wildner print_otag(h, TAG_DD, "");
76454ba9607SSascha Wildner break;
76554ba9607SSascha Wildner default:
76654ba9607SSascha Wildner break;
76754ba9607SSascha Wildner }
76854ba9607SSascha Wildner break;
769070c62a6SFranco Fichtner case LIST_tag:
77054ba9607SSascha Wildner switch (n->type) {
77154ba9607SSascha Wildner case ROFFT_HEAD:
772*99db7d0eSSascha Wildner print_otag_id(h, TAG_DT, NULL, n);
77380387638SSascha Wildner break;
77454ba9607SSascha Wildner case ROFFT_BODY:
77554ba9607SSascha Wildner if (n->child == NULL) {
77654ba9607SSascha Wildner print_otag(h, TAG_DD, "s", "width", "auto");
77754ba9607SSascha Wildner print_text(h, "\\ ");
77854ba9607SSascha Wildner } else
77954ba9607SSascha Wildner print_otag(h, TAG_DD, "");
78080387638SSascha Wildner break;
78180387638SSascha Wildner default:
78280387638SSascha Wildner break;
78380387638SSascha Wildner }
78454ba9607SSascha Wildner break;
785070c62a6SFranco Fichtner case LIST_column:
78654ba9607SSascha Wildner switch (n->type) {
78754ba9607SSascha Wildner case ROFFT_HEAD:
78854ba9607SSascha Wildner break;
78954ba9607SSascha Wildner case ROFFT_BODY:
79054ba9607SSascha Wildner print_otag(h, TAG_TD, "");
79180387638SSascha Wildner break;
79280387638SSascha Wildner default:
793*99db7d0eSSascha Wildner print_otag_id(h, TAG_TR, NULL, n);
79480387638SSascha Wildner }
79554ba9607SSascha Wildner default:
79654ba9607SSascha Wildner break;
79780387638SSascha Wildner }
79880387638SSascha Wildner
79954ba9607SSascha Wildner return 1;
80080387638SSascha Wildner }
80180387638SSascha Wildner
80280387638SSascha Wildner static int
mdoc_bl_pre(MDOC_ARGS)80380387638SSascha Wildner mdoc_bl_pre(MDOC_ARGS)
80480387638SSascha Wildner {
80554ba9607SSascha Wildner char cattr[32];
80654ba9607SSascha Wildner struct mdoc_bl *bl;
80754ba9607SSascha Wildner enum htmltag elemtype;
80880387638SSascha Wildner
80954ba9607SSascha Wildner switch (n->type) {
81054ba9607SSascha Wildner case ROFFT_BLOCK:
81154ba9607SSascha Wildner html_close_paragraph(h);
81254ba9607SSascha Wildner break;
81354ba9607SSascha Wildner case ROFFT_HEAD:
81454ba9607SSascha Wildner return 0;
81554ba9607SSascha Wildner case ROFFT_BODY:
81654ba9607SSascha Wildner return 1;
81754ba9607SSascha Wildner default:
81854ba9607SSascha Wildner abort();
81980387638SSascha Wildner }
82080387638SSascha Wildner
82154ba9607SSascha Wildner bl = &n->norm->Bl;
82254ba9607SSascha Wildner switch (bl->type) {
823070c62a6SFranco Fichtner case LIST_bullet:
82454ba9607SSascha Wildner elemtype = TAG_UL;
82554ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-bullet", sizeof(cattr));
82654ba9607SSascha Wildner break;
827070c62a6SFranco Fichtner case LIST_dash:
828070c62a6SFranco Fichtner case LIST_hyphen:
82954ba9607SSascha Wildner elemtype = TAG_UL;
83054ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-dash", sizeof(cattr));
83154ba9607SSascha Wildner break;
832070c62a6SFranco Fichtner case LIST_item:
83354ba9607SSascha Wildner elemtype = TAG_UL;
83454ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-item", sizeof(cattr));
83580387638SSascha Wildner break;
836070c62a6SFranco Fichtner case LIST_enum:
83754ba9607SSascha Wildner elemtype = TAG_OL;
83854ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-enum", sizeof(cattr));
83980387638SSascha Wildner break;
840070c62a6SFranco Fichtner case LIST_diag:
84154ba9607SSascha Wildner elemtype = TAG_DL;
84254ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-diag", sizeof(cattr));
84380387638SSascha Wildner break;
84454ba9607SSascha Wildner case LIST_hang:
84554ba9607SSascha Wildner elemtype = TAG_DL;
84654ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-hang", sizeof(cattr));
84754ba9607SSascha Wildner break;
84854ba9607SSascha Wildner case LIST_inset:
84954ba9607SSascha Wildner elemtype = TAG_DL;
85054ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-inset", sizeof(cattr));
85154ba9607SSascha Wildner break;
85254ba9607SSascha Wildner case LIST_ohang:
85354ba9607SSascha Wildner elemtype = TAG_DL;
85454ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-ohang", sizeof(cattr));
85554ba9607SSascha Wildner break;
85654ba9607SSascha Wildner case LIST_tag:
85754ba9607SSascha Wildner if (bl->offs)
85854ba9607SSascha Wildner print_otag(h, TAG_DIV, "c", "Bd-indent");
859*99db7d0eSSascha Wildner print_otag_id(h, TAG_DL,
860*99db7d0eSSascha Wildner bl->comp ? "Bl-tag Bl-compact" : "Bl-tag", n->body);
86154ba9607SSascha Wildner return 1;
862070c62a6SFranco Fichtner case LIST_column:
86354ba9607SSascha Wildner elemtype = TAG_TABLE;
86454ba9607SSascha Wildner (void)strlcpy(cattr, "Bl-column", sizeof(cattr));
86580387638SSascha Wildner break;
86680387638SSascha Wildner default:
86780387638SSascha Wildner abort();
86880387638SSascha Wildner }
86954ba9607SSascha Wildner if (bl->offs != NULL)
87054ba9607SSascha Wildner (void)strlcat(cattr, " Bd-indent", sizeof(cattr));
87154ba9607SSascha Wildner if (bl->comp)
87254ba9607SSascha Wildner (void)strlcat(cattr, " Bl-compact", sizeof(cattr));
873*99db7d0eSSascha Wildner print_otag_id(h, elemtype, cattr, n->body);
87454ba9607SSascha Wildner return 1;
87580387638SSascha Wildner }
87680387638SSascha Wildner
87780387638SSascha Wildner static int
mdoc_ex_pre(MDOC_ARGS)87880387638SSascha Wildner mdoc_ex_pre(MDOC_ARGS)
87980387638SSascha Wildner {
880*99db7d0eSSascha Wildner if (roff_node_prev(n) != NULL)
88154ba9607SSascha Wildner print_otag(h, TAG_BR, "");
88254ba9607SSascha Wildner return 1;
88380387638SSascha Wildner }
88480387638SSascha Wildner
88554ba9607SSascha Wildner static int
mdoc_st_pre(MDOC_ARGS)88654ba9607SSascha Wildner mdoc_st_pre(MDOC_ARGS)
88754ba9607SSascha Wildner {
88854ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "St");
88954ba9607SSascha Wildner return 1;
89080387638SSascha Wildner }
89180387638SSascha Wildner
89280387638SSascha Wildner static int
mdoc_em_pre(MDOC_ARGS)89380387638SSascha Wildner mdoc_em_pre(MDOC_ARGS)
89480387638SSascha Wildner {
895*99db7d0eSSascha Wildner print_otag_id(h, TAG_I, "Em", n);
89654ba9607SSascha Wildner return 1;
89780387638SSascha Wildner }
89880387638SSascha Wildner
89980387638SSascha Wildner static int
mdoc_d1_pre(MDOC_ARGS)90080387638SSascha Wildner mdoc_d1_pre(MDOC_ARGS)
90180387638SSascha Wildner {
90254ba9607SSascha Wildner switch (n->type) {
90354ba9607SSascha Wildner case ROFFT_BLOCK:
90454ba9607SSascha Wildner html_close_paragraph(h);
905*99db7d0eSSascha Wildner return 1;
90654ba9607SSascha Wildner case ROFFT_HEAD:
90754ba9607SSascha Wildner return 0;
90854ba9607SSascha Wildner case ROFFT_BODY:
909*99db7d0eSSascha Wildner break;
91054ba9607SSascha Wildner default:
91154ba9607SSascha Wildner abort();
91280387638SSascha Wildner }
913*99db7d0eSSascha Wildner print_otag_id(h, TAG_DIV, "Bd Bd-indent", n);
91454ba9607SSascha Wildner if (n->tok == MDOC_Dl)
91554ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "Li");
91654ba9607SSascha Wildner return 1;
91780387638SSascha Wildner }
91880387638SSascha Wildner
91980387638SSascha Wildner static int
mdoc_sx_pre(MDOC_ARGS)92080387638SSascha Wildner mdoc_sx_pre(MDOC_ARGS)
92180387638SSascha Wildner {
92254ba9607SSascha Wildner char *id;
92380387638SSascha Wildner
92454ba9607SSascha Wildner id = html_make_id(n, 0);
92554ba9607SSascha Wildner print_otag(h, TAG_A, "chR", "Sx", id);
92654ba9607SSascha Wildner free(id);
92754ba9607SSascha Wildner return 1;
92880387638SSascha Wildner }
92980387638SSascha Wildner
93080387638SSascha Wildner static int
mdoc_bd_pre(MDOC_ARGS)93180387638SSascha Wildner mdoc_bd_pre(MDOC_ARGS)
93280387638SSascha Wildner {
933*99db7d0eSSascha Wildner char buf[20];
93454ba9607SSascha Wildner struct roff_node *nn;
93554ba9607SSascha Wildner int comp;
93680387638SSascha Wildner
93754ba9607SSascha Wildner switch (n->type) {
93854ba9607SSascha Wildner case ROFFT_BLOCK:
93954ba9607SSascha Wildner html_close_paragraph(h);
94054ba9607SSascha Wildner return 1;
94154ba9607SSascha Wildner case ROFFT_HEAD:
94254ba9607SSascha Wildner return 0;
94354ba9607SSascha Wildner case ROFFT_BODY:
94480387638SSascha Wildner break;
94580387638SSascha Wildner default:
94654ba9607SSascha Wildner abort();
94754ba9607SSascha Wildner }
94854ba9607SSascha Wildner
94954ba9607SSascha Wildner /* Handle preceding whitespace. */
95054ba9607SSascha Wildner
95154ba9607SSascha Wildner comp = n->norm->Bd.comp;
95254ba9607SSascha Wildner for (nn = n; nn != NULL && comp == 0; nn = nn->parent) {
95354ba9607SSascha Wildner if (nn->type != ROFFT_BLOCK)
95454ba9607SSascha Wildner continue;
95554ba9607SSascha Wildner if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss)
95654ba9607SSascha Wildner comp = 1;
957*99db7d0eSSascha Wildner if (roff_node_prev(nn) != NULL)
95880387638SSascha Wildner break;
95980387638SSascha Wildner }
96054ba9607SSascha Wildner (void)strlcpy(buf, "Bd", sizeof(buf));
96154ba9607SSascha Wildner if (comp == 0)
96254ba9607SSascha Wildner (void)strlcat(buf, " Pp", sizeof(buf));
96380387638SSascha Wildner
96454ba9607SSascha Wildner /* Handle the -offset argument. */
96580387638SSascha Wildner
96654ba9607SSascha Wildner if (n->norm->Bd.offs != NULL &&
96754ba9607SSascha Wildner strcmp(n->norm->Bd.offs, "left") != 0)
96854ba9607SSascha Wildner (void)strlcat(buf, " Bd-indent", sizeof(buf));
96960e1e752SSascha Wildner
970*99db7d0eSSascha Wildner if (n->norm->Bd.type == DISP_literal)
971*99db7d0eSSascha Wildner (void)strlcat(buf, " Li", sizeof(buf));
972*99db7d0eSSascha Wildner
973*99db7d0eSSascha Wildner print_otag_id(h, TAG_DIV, buf, n);
97454ba9607SSascha Wildner return 1;
97580387638SSascha Wildner }
97680387638SSascha Wildner
97780387638SSascha Wildner static int
mdoc_pa_pre(MDOC_ARGS)97880387638SSascha Wildner mdoc_pa_pre(MDOC_ARGS)
97980387638SSascha Wildner {
98054ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "Pa");
98154ba9607SSascha Wildner return 1;
98280387638SSascha Wildner }
98380387638SSascha Wildner
98480387638SSascha Wildner static int
mdoc_ad_pre(MDOC_ARGS)98580387638SSascha Wildner mdoc_ad_pre(MDOC_ARGS)
98680387638SSascha Wildner {
98754ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "Ad");
98854ba9607SSascha Wildner return 1;
98980387638SSascha Wildner }
99080387638SSascha Wildner
99180387638SSascha Wildner static int
mdoc_an_pre(MDOC_ARGS)99280387638SSascha Wildner mdoc_an_pre(MDOC_ARGS)
99380387638SSascha Wildner {
99454ba9607SSascha Wildner if (n->norm->An.auth == AUTH_split) {
99554ba9607SSascha Wildner h->flags &= ~HTML_NOSPLIT;
99654ba9607SSascha Wildner h->flags |= HTML_SPLIT;
99754ba9607SSascha Wildner return 0;
99854ba9607SSascha Wildner }
99954ba9607SSascha Wildner if (n->norm->An.auth == AUTH_nosplit) {
100054ba9607SSascha Wildner h->flags &= ~HTML_SPLIT;
100154ba9607SSascha Wildner h->flags |= HTML_NOSPLIT;
100254ba9607SSascha Wildner return 0;
100354ba9607SSascha Wildner }
100480387638SSascha Wildner
100554ba9607SSascha Wildner if (h->flags & HTML_SPLIT)
100654ba9607SSascha Wildner print_otag(h, TAG_BR, "");
100780387638SSascha Wildner
100854ba9607SSascha Wildner if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT))
100954ba9607SSascha Wildner h->flags |= HTML_SPLIT;
101054ba9607SSascha Wildner
101154ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "An");
101254ba9607SSascha Wildner return 1;
101380387638SSascha Wildner }
101480387638SSascha Wildner
101580387638SSascha Wildner static int
mdoc_cd_pre(MDOC_ARGS)101680387638SSascha Wildner mdoc_cd_pre(MDOC_ARGS)
101780387638SSascha Wildner {
101880387638SSascha Wildner synopsis_pre(h, n);
101954ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "Cd");
102054ba9607SSascha Wildner return 1;
102180387638SSascha Wildner }
102280387638SSascha Wildner
102380387638SSascha Wildner static int
mdoc_fa_pre(MDOC_ARGS)102480387638SSascha Wildner mdoc_fa_pre(MDOC_ARGS)
102580387638SSascha Wildner {
102654ba9607SSascha Wildner const struct roff_node *nn;
102780387638SSascha Wildner struct tag *t;
102880387638SSascha Wildner
102980387638SSascha Wildner if (n->parent->tok != MDOC_Fo) {
103054ba9607SSascha Wildner print_otag(h, TAG_VAR, "c", "Fa");
103154ba9607SSascha Wildner return 1;
103280387638SSascha Wildner }
1033*99db7d0eSSascha Wildner for (nn = n->child; nn != NULL; nn = nn->next) {
103454ba9607SSascha Wildner t = print_otag(h, TAG_VAR, "c", "Fa");
103580387638SSascha Wildner print_text(h, nn->string);
103680387638SSascha Wildner print_tagq(h, t);
1037*99db7d0eSSascha Wildner if (nn->next != NULL) {
103860e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
103980387638SSascha Wildner print_text(h, ",");
104080387638SSascha Wildner }
104160e1e752SSascha Wildner }
1042*99db7d0eSSascha Wildner if (n->child != NULL &&
1043*99db7d0eSSascha Wildner (nn = roff_node_next(n)) != NULL &&
1044*99db7d0eSSascha Wildner nn->tok == MDOC_Fa) {
104560e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
104680387638SSascha Wildner print_text(h, ",");
104760e1e752SSascha Wildner }
104854ba9607SSascha Wildner return 0;
104980387638SSascha Wildner }
105080387638SSascha Wildner
105180387638SSascha Wildner static int
mdoc_fd_pre(MDOC_ARGS)105280387638SSascha Wildner mdoc_fd_pre(MDOC_ARGS)
105380387638SSascha Wildner {
105460e1e752SSascha Wildner struct tag *t;
105554ba9607SSascha Wildner char *buf, *cp;
105680387638SSascha Wildner
105780387638SSascha Wildner synopsis_pre(h, n);
105880387638SSascha Wildner
105960e1e752SSascha Wildner if (NULL == (n = n->child))
106054ba9607SSascha Wildner return 0;
106160e1e752SSascha Wildner
106254ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
106360e1e752SSascha Wildner
106460e1e752SSascha Wildner if (strcmp(n->string, "#include")) {
106554ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "Fd");
106654ba9607SSascha Wildner return 1;
106780387638SSascha Wildner }
106880387638SSascha Wildner
106954ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "In");
107060e1e752SSascha Wildner print_text(h, n->string);
107160e1e752SSascha Wildner
107260e1e752SSascha Wildner if (NULL != (n = n->next)) {
107354ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
1074070c62a6SFranco Fichtner
107560e1e752SSascha Wildner if (h->base_includes) {
107654ba9607SSascha Wildner cp = n->string;
107754ba9607SSascha Wildner if (*cp == '<' || *cp == '"')
107854ba9607SSascha Wildner cp++;
107954ba9607SSascha Wildner buf = mandoc_strdup(cp);
108054ba9607SSascha Wildner cp = strchr(buf, '\0') - 1;
108154ba9607SSascha Wildner if (cp >= buf && (*cp == '>' || *cp == '"'))
108254ba9607SSascha Wildner *cp = '\0';
108354ba9607SSascha Wildner t = print_otag(h, TAG_A, "chI", "In", buf);
108454ba9607SSascha Wildner free(buf);
108554ba9607SSascha Wildner } else
108654ba9607SSascha Wildner t = print_otag(h, TAG_A, "c", "In");
108760e1e752SSascha Wildner
108860e1e752SSascha Wildner print_text(h, n->string);
108960e1e752SSascha Wildner print_tagq(h, t);
109060e1e752SSascha Wildner
109160e1e752SSascha Wildner n = n->next;
109260e1e752SSascha Wildner }
109360e1e752SSascha Wildner
109460e1e752SSascha Wildner for ( ; n; n = n->next) {
109554ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
109660e1e752SSascha Wildner print_text(h, n->string);
109760e1e752SSascha Wildner }
109860e1e752SSascha Wildner
109954ba9607SSascha Wildner return 0;
110060e1e752SSascha Wildner }
110160e1e752SSascha Wildner
110280387638SSascha Wildner static int
mdoc_vt_pre(MDOC_ARGS)110380387638SSascha Wildner mdoc_vt_pre(MDOC_ARGS)
110480387638SSascha Wildner {
110554ba9607SSascha Wildner if (n->type == ROFFT_BLOCK) {
110680387638SSascha Wildner synopsis_pre(h, n);
110754ba9607SSascha Wildner return 1;
110854ba9607SSascha Wildner } else if (n->type == ROFFT_ELEM) {
110980387638SSascha Wildner synopsis_pre(h, n);
111054ba9607SSascha Wildner } else if (n->type == ROFFT_HEAD)
111154ba9607SSascha Wildner return 0;
111280387638SSascha Wildner
111354ba9607SSascha Wildner print_otag(h, TAG_VAR, "c", "Vt");
111454ba9607SSascha Wildner return 1;
111580387638SSascha Wildner }
111680387638SSascha Wildner
111780387638SSascha Wildner static int
mdoc_ft_pre(MDOC_ARGS)111880387638SSascha Wildner mdoc_ft_pre(MDOC_ARGS)
111980387638SSascha Wildner {
112080387638SSascha Wildner synopsis_pre(h, n);
112154ba9607SSascha Wildner print_otag(h, TAG_VAR, "c", "Ft");
112254ba9607SSascha Wildner return 1;
112380387638SSascha Wildner }
112480387638SSascha Wildner
112580387638SSascha Wildner static int
mdoc_fn_pre(MDOC_ARGS)112680387638SSascha Wildner mdoc_fn_pre(MDOC_ARGS)
112780387638SSascha Wildner {
112880387638SSascha Wildner struct tag *t;
112980387638SSascha Wildner char nbuf[BUFSIZ];
113080387638SSascha Wildner const char *sp, *ep;
113154ba9607SSascha Wildner int sz, pretty;
113280387638SSascha Wildner
113354ba9607SSascha Wildner pretty = NODE_SYNPRETTY & n->flags;
113480387638SSascha Wildner synopsis_pre(h, n);
113580387638SSascha Wildner
113680387638SSascha Wildner /* Split apart into type and name. */
113780387638SSascha Wildner assert(n->child->string);
113880387638SSascha Wildner sp = n->child->string;
113980387638SSascha Wildner
114080387638SSascha Wildner ep = strchr(sp, ' ');
114180387638SSascha Wildner if (NULL != ep) {
114254ba9607SSascha Wildner t = print_otag(h, TAG_VAR, "c", "Ft");
114380387638SSascha Wildner
114480387638SSascha Wildner while (ep) {
114580387638SSascha Wildner sz = MIN((int)(ep - sp), BUFSIZ - 1);
114680387638SSascha Wildner (void)memcpy(nbuf, sp, (size_t)sz);
114780387638SSascha Wildner nbuf[sz] = '\0';
114880387638SSascha Wildner print_text(h, nbuf);
114980387638SSascha Wildner sp = ++ep;
115080387638SSascha Wildner ep = strchr(sp, ' ');
115180387638SSascha Wildner }
115280387638SSascha Wildner print_tagq(h, t);
115380387638SSascha Wildner }
115480387638SSascha Wildner
1155*99db7d0eSSascha Wildner t = print_otag_id(h, TAG_CODE, "Fn", n);
115680387638SSascha Wildner
1157070c62a6SFranco Fichtner if (sp)
1158070c62a6SFranco Fichtner print_text(h, sp);
115980387638SSascha Wildner
116080387638SSascha Wildner print_tagq(h, t);
116180387638SSascha Wildner
116280387638SSascha Wildner h->flags |= HTML_NOSPACE;
116380387638SSascha Wildner print_text(h, "(");
1164a4c7eb57SSascha Wildner h->flags |= HTML_NOSPACE;
116580387638SSascha Wildner
116660e1e752SSascha Wildner for (n = n->child->next; n; n = n->next) {
116754ba9607SSascha Wildner if (NODE_SYNPRETTY & n->flags)
116854ba9607SSascha Wildner t = print_otag(h, TAG_VAR, "cs", "Fa",
116954ba9607SSascha Wildner "white-space", "nowrap");
117054ba9607SSascha Wildner else
117154ba9607SSascha Wildner t = print_otag(h, TAG_VAR, "c", "Fa");
117260e1e752SSascha Wildner print_text(h, n->string);
117380387638SSascha Wildner print_tagq(h, t);
117460e1e752SSascha Wildner if (n->next) {
117560e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
117680387638SSascha Wildner print_text(h, ",");
117780387638SSascha Wildner }
117860e1e752SSascha Wildner }
117980387638SSascha Wildner
118060e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
118180387638SSascha Wildner print_text(h, ")");
118260e1e752SSascha Wildner
118360e1e752SSascha Wildner if (pretty) {
118460e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
118580387638SSascha Wildner print_text(h, ";");
118660e1e752SSascha Wildner }
118780387638SSascha Wildner
118854ba9607SSascha Wildner return 0;
118980387638SSascha Wildner }
119080387638SSascha Wildner
119180387638SSascha Wildner static int
mdoc_sm_pre(MDOC_ARGS)119280387638SSascha Wildner mdoc_sm_pre(MDOC_ARGS)
119380387638SSascha Wildner {
119480387638SSascha Wildner
1195070c62a6SFranco Fichtner if (NULL == n->child)
1196070c62a6SFranco Fichtner h->flags ^= HTML_NONOSPACE;
1197070c62a6SFranco Fichtner else if (0 == strcmp("on", n->child->string))
119880387638SSascha Wildner h->flags &= ~HTML_NONOSPACE;
1199070c62a6SFranco Fichtner else
120080387638SSascha Wildner h->flags |= HTML_NONOSPACE;
120180387638SSascha Wildner
1202070c62a6SFranco Fichtner if ( ! (HTML_NONOSPACE & h->flags))
1203070c62a6SFranco Fichtner h->flags &= ~HTML_NOSPACE;
1204070c62a6SFranco Fichtner
120554ba9607SSascha Wildner return 0;
120680387638SSascha Wildner }
120780387638SSascha Wildner
1208070c62a6SFranco Fichtner static int
mdoc_skip_pre(MDOC_ARGS)1209070c62a6SFranco Fichtner mdoc_skip_pre(MDOC_ARGS)
1210070c62a6SFranco Fichtner {
1211070c62a6SFranco Fichtner
121254ba9607SSascha Wildner return 0;
1213070c62a6SFranco Fichtner }
1214070c62a6SFranco Fichtner
121580387638SSascha Wildner static int
mdoc_pp_pre(MDOC_ARGS)121680387638SSascha Wildner mdoc_pp_pre(MDOC_ARGS)
121780387638SSascha Wildner {
1218*99db7d0eSSascha Wildner char *id;
1219*99db7d0eSSascha Wildner
1220*99db7d0eSSascha Wildner if (n->flags & NODE_NOFILL) {
1221*99db7d0eSSascha Wildner print_endline(h);
1222*99db7d0eSSascha Wildner if (n->flags & NODE_ID)
1223*99db7d0eSSascha Wildner mdoc_tg_pre(meta, n, h);
1224*99db7d0eSSascha Wildner else {
1225*99db7d0eSSascha Wildner h->col = 1;
1226*99db7d0eSSascha Wildner print_endline(h);
1227*99db7d0eSSascha Wildner }
1228*99db7d0eSSascha Wildner } else {
122954ba9607SSascha Wildner html_close_paragraph(h);
1230*99db7d0eSSascha Wildner id = n->flags & NODE_ID ? html_make_id(n, 1) : NULL;
1231*99db7d0eSSascha Wildner print_otag(h, TAG_P, "ci", "Pp", id);
1232*99db7d0eSSascha Wildner free(id);
123380387638SSascha Wildner }
123454ba9607SSascha Wildner return 0;
123580387638SSascha Wildner }
123680387638SSascha Wildner
123780387638SSascha Wildner static int
mdoc_lk_pre(MDOC_ARGS)123880387638SSascha Wildner mdoc_lk_pre(MDOC_ARGS)
123980387638SSascha Wildner {
124054ba9607SSascha Wildner const struct roff_node *link, *descr, *punct;
124154ba9607SSascha Wildner struct tag *t;
124280387638SSascha Wildner
124354ba9607SSascha Wildner if ((link = n->child) == NULL)
124454ba9607SSascha Wildner return 0;
124560e1e752SSascha Wildner
124654ba9607SSascha Wildner /* Find beginning of trailing punctuation. */
124754ba9607SSascha Wildner punct = n->last;
124854ba9607SSascha Wildner while (punct != link && punct->flags & NODE_DELIMC)
124954ba9607SSascha Wildner punct = punct->prev;
125054ba9607SSascha Wildner punct = punct->next;
125180387638SSascha Wildner
125254ba9607SSascha Wildner /* Link target and link text. */
125354ba9607SSascha Wildner descr = link->next;
125454ba9607SSascha Wildner if (descr == punct)
125554ba9607SSascha Wildner descr = link; /* no text */
125654ba9607SSascha Wildner t = print_otag(h, TAG_A, "ch", "Lk", link->string);
125754ba9607SSascha Wildner do {
125854ba9607SSascha Wildner if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
125954ba9607SSascha Wildner h->flags |= HTML_NOSPACE;
126054ba9607SSascha Wildner print_text(h, descr->string);
126154ba9607SSascha Wildner descr = descr->next;
126254ba9607SSascha Wildner } while (descr != punct);
126354ba9607SSascha Wildner print_tagq(h, t);
126460e1e752SSascha Wildner
126554ba9607SSascha Wildner /* Trailing punctuation. */
126654ba9607SSascha Wildner while (punct != NULL) {
126754ba9607SSascha Wildner h->flags |= HTML_NOSPACE;
126854ba9607SSascha Wildner print_text(h, punct->string);
126954ba9607SSascha Wildner punct = punct->next;
127054ba9607SSascha Wildner }
127154ba9607SSascha Wildner return 0;
127280387638SSascha Wildner }
127380387638SSascha Wildner
127480387638SSascha Wildner static int
mdoc_mt_pre(MDOC_ARGS)127580387638SSascha Wildner mdoc_mt_pre(MDOC_ARGS)
127680387638SSascha Wildner {
127780387638SSascha Wildner struct tag *t;
127854ba9607SSascha Wildner char *cp;
127980387638SSascha Wildner
128060e1e752SSascha Wildner for (n = n->child; n; n = n->next) {
128154ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
128254ba9607SSascha Wildner mandoc_asprintf(&cp, "mailto:%s", n->string);
128354ba9607SSascha Wildner t = print_otag(h, TAG_A, "ch", "Mt", cp);
128460e1e752SSascha Wildner print_text(h, n->string);
128580387638SSascha Wildner print_tagq(h, t);
128654ba9607SSascha Wildner free(cp);
128780387638SSascha Wildner }
128854ba9607SSascha Wildner return 0;
128980387638SSascha Wildner }
129080387638SSascha Wildner
129180387638SSascha Wildner static int
mdoc_fo_pre(MDOC_ARGS)129280387638SSascha Wildner mdoc_fo_pre(MDOC_ARGS)
129380387638SSascha Wildner {
129480387638SSascha Wildner struct tag *t;
129580387638SSascha Wildner
1296*99db7d0eSSascha Wildner switch (n->type) {
1297*99db7d0eSSascha Wildner case ROFFT_BLOCK:
1298*99db7d0eSSascha Wildner synopsis_pre(h, n);
1299*99db7d0eSSascha Wildner return 1;
1300*99db7d0eSSascha Wildner case ROFFT_HEAD:
1301*99db7d0eSSascha Wildner if (n->child != NULL) {
1302*99db7d0eSSascha Wildner t = print_otag_id(h, TAG_CODE, "Fn", n);
1303*99db7d0eSSascha Wildner print_text(h, n->child->string);
1304*99db7d0eSSascha Wildner print_tagq(h, t);
1305*99db7d0eSSascha Wildner }
1306*99db7d0eSSascha Wildner return 0;
1307*99db7d0eSSascha Wildner case ROFFT_BODY:
130880387638SSascha Wildner h->flags |= HTML_NOSPACE;
130980387638SSascha Wildner print_text(h, "(");
131080387638SSascha Wildner h->flags |= HTML_NOSPACE;
131154ba9607SSascha Wildner return 1;
1312*99db7d0eSSascha Wildner default:
1313*99db7d0eSSascha Wildner abort();
131480387638SSascha Wildner }
131580387638SSascha Wildner }
131680387638SSascha Wildner
131780387638SSascha Wildner static void
mdoc_fo_post(MDOC_ARGS)131880387638SSascha Wildner mdoc_fo_post(MDOC_ARGS)
131980387638SSascha Wildner {
132054ba9607SSascha Wildner if (n->type != ROFFT_BODY)
132180387638SSascha Wildner return;
132260e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
132380387638SSascha Wildner print_text(h, ")");
132460e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
132580387638SSascha Wildner print_text(h, ";");
132680387638SSascha Wildner }
132780387638SSascha Wildner
132880387638SSascha Wildner static int
mdoc_in_pre(MDOC_ARGS)132980387638SSascha Wildner mdoc_in_pre(MDOC_ARGS)
133080387638SSascha Wildner {
133180387638SSascha Wildner struct tag *t;
133280387638SSascha Wildner
133380387638SSascha Wildner synopsis_pre(h, n);
133454ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "In");
133580387638SSascha Wildner
133660e1e752SSascha Wildner /*
133760e1e752SSascha Wildner * The first argument of the `In' gets special treatment as
133860e1e752SSascha Wildner * being a linked value. Subsequent values are printed
133960e1e752SSascha Wildner * afterward. groff does similarly. This also handles the case
134060e1e752SSascha Wildner * of no children.
134160e1e752SSascha Wildner */
134260e1e752SSascha Wildner
134354ba9607SSascha Wildner if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags)
134480387638SSascha Wildner print_text(h, "#include");
134580387638SSascha Wildner
134680387638SSascha Wildner print_text(h, "<");
134780387638SSascha Wildner h->flags |= HTML_NOSPACE;
134880387638SSascha Wildner
134960e1e752SSascha Wildner if (NULL != (n = n->child)) {
135054ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
135160e1e752SSascha Wildner
135254ba9607SSascha Wildner if (h->base_includes)
135354ba9607SSascha Wildner t = print_otag(h, TAG_A, "chI", "In", n->string);
135454ba9607SSascha Wildner else
135554ba9607SSascha Wildner t = print_otag(h, TAG_A, "c", "In");
135660e1e752SSascha Wildner print_text(h, n->string);
135780387638SSascha Wildner print_tagq(h, t);
135860e1e752SSascha Wildner
135960e1e752SSascha Wildner n = n->next;
136080387638SSascha Wildner }
136180387638SSascha Wildner
136280387638SSascha Wildner h->flags |= HTML_NOSPACE;
136380387638SSascha Wildner print_text(h, ">");
136480387638SSascha Wildner
136560e1e752SSascha Wildner for ( ; n; n = n->next) {
136654ba9607SSascha Wildner assert(n->type == ROFFT_TEXT);
136760e1e752SSascha Wildner print_text(h, n->string);
136860e1e752SSascha Wildner }
136954ba9607SSascha Wildner return 0;
137080387638SSascha Wildner }
137180387638SSascha Wildner
137280387638SSascha Wildner static int
mdoc_va_pre(MDOC_ARGS)137380387638SSascha Wildner mdoc_va_pre(MDOC_ARGS)
137480387638SSascha Wildner {
137554ba9607SSascha Wildner print_otag(h, TAG_VAR, "c", "Va");
137654ba9607SSascha Wildner return 1;
137780387638SSascha Wildner }
137880387638SSascha Wildner
137980387638SSascha Wildner static int
mdoc_ap_pre(MDOC_ARGS)138080387638SSascha Wildner mdoc_ap_pre(MDOC_ARGS)
138180387638SSascha Wildner {
138280387638SSascha Wildner h->flags |= HTML_NOSPACE;
138380387638SSascha Wildner print_text(h, "\\(aq");
138480387638SSascha Wildner h->flags |= HTML_NOSPACE;
138554ba9607SSascha Wildner return 1;
138680387638SSascha Wildner }
138780387638SSascha Wildner
138880387638SSascha Wildner static int
mdoc_bf_pre(MDOC_ARGS)138980387638SSascha Wildner mdoc_bf_pre(MDOC_ARGS)
139080387638SSascha Wildner {
139154ba9607SSascha Wildner const char *cattr;
139280387638SSascha Wildner
139354ba9607SSascha Wildner switch (n->type) {
139454ba9607SSascha Wildner case ROFFT_BLOCK:
139554ba9607SSascha Wildner html_close_paragraph(h);
139654ba9607SSascha Wildner return 1;
139754ba9607SSascha Wildner case ROFFT_HEAD:
139854ba9607SSascha Wildner return 0;
139954ba9607SSascha Wildner case ROFFT_BODY:
140054ba9607SSascha Wildner break;
140154ba9607SSascha Wildner default:
140254ba9607SSascha Wildner abort();
140354ba9607SSascha Wildner }
140480387638SSascha Wildner
140580387638SSascha Wildner if (FONT_Em == n->norm->Bf.font)
140654ba9607SSascha Wildner cattr = "Bf Em";
140780387638SSascha Wildner else if (FONT_Sy == n->norm->Bf.font)
140854ba9607SSascha Wildner cattr = "Bf Sy";
140980387638SSascha Wildner else if (FONT_Li == n->norm->Bf.font)
141054ba9607SSascha Wildner cattr = "Bf Li";
141180387638SSascha Wildner else
141254ba9607SSascha Wildner cattr = "Bf No";
141380387638SSascha Wildner
141454ba9607SSascha Wildner /* Cannot use TAG_SPAN because it may contain blocks. */
141554ba9607SSascha Wildner print_otag(h, TAG_DIV, "c", cattr);
141654ba9607SSascha Wildner return 1;
141780387638SSascha Wildner }
141880387638SSascha Wildner
141980387638SSascha Wildner static int
mdoc_igndelim_pre(MDOC_ARGS)142080387638SSascha Wildner mdoc_igndelim_pre(MDOC_ARGS)
142180387638SSascha Wildner {
142280387638SSascha Wildner h->flags |= HTML_IGNDELIM;
142354ba9607SSascha Wildner return 1;
142480387638SSascha Wildner }
142580387638SSascha Wildner
142680387638SSascha Wildner static void
mdoc_pf_post(MDOC_ARGS)142780387638SSascha Wildner mdoc_pf_post(MDOC_ARGS)
142880387638SSascha Wildner {
142954ba9607SSascha Wildner if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
143080387638SSascha Wildner h->flags |= HTML_NOSPACE;
143180387638SSascha Wildner }
143280387638SSascha Wildner
143380387638SSascha Wildner static int
mdoc_rs_pre(MDOC_ARGS)143480387638SSascha Wildner mdoc_rs_pre(MDOC_ARGS)
143580387638SSascha Wildner {
143654ba9607SSascha Wildner switch (n->type) {
143754ba9607SSascha Wildner case ROFFT_BLOCK:
143854ba9607SSascha Wildner if (n->sec == SEC_SEE_ALSO)
143954ba9607SSascha Wildner html_close_paragraph(h);
144054ba9607SSascha Wildner break;
144154ba9607SSascha Wildner case ROFFT_HEAD:
144254ba9607SSascha Wildner return 0;
144354ba9607SSascha Wildner case ROFFT_BODY:
144454ba9607SSascha Wildner if (n->sec == SEC_SEE_ALSO)
144554ba9607SSascha Wildner print_otag(h, TAG_P, "c", "Pp");
144654ba9607SSascha Wildner print_otag(h, TAG_CITE, "c", "Rs");
144754ba9607SSascha Wildner break;
144854ba9607SSascha Wildner default:
144954ba9607SSascha Wildner abort();
145054ba9607SSascha Wildner }
145154ba9607SSascha Wildner return 1;
145254ba9607SSascha Wildner }
145380387638SSascha Wildner
145454ba9607SSascha Wildner static int
mdoc_no_pre(MDOC_ARGS)145554ba9607SSascha Wildner mdoc_no_pre(MDOC_ARGS)
145654ba9607SSascha Wildner {
1457*99db7d0eSSascha Wildner print_otag_id(h, TAG_SPAN, roff_name[n->tok], n);
145854ba9607SSascha Wildner return 1;
145980387638SSascha Wildner }
146080387638SSascha Wildner
146180387638SSascha Wildner static int
mdoc_sy_pre(MDOC_ARGS)146280387638SSascha Wildner mdoc_sy_pre(MDOC_ARGS)
146380387638SSascha Wildner {
1464*99db7d0eSSascha Wildner print_otag_id(h, TAG_B, "Sy", n);
146554ba9607SSascha Wildner return 1;
146680387638SSascha Wildner }
146780387638SSascha Wildner
146880387638SSascha Wildner static int
mdoc_lb_pre(MDOC_ARGS)146980387638SSascha Wildner mdoc_lb_pre(MDOC_ARGS)
147080387638SSascha Wildner {
1471*99db7d0eSSascha Wildner if (n->sec == SEC_LIBRARY &&
1472*99db7d0eSSascha Wildner n->flags & NODE_LINE &&
1473*99db7d0eSSascha Wildner roff_node_prev(n) != NULL)
147454ba9607SSascha Wildner print_otag(h, TAG_BR, "");
147580387638SSascha Wildner
147654ba9607SSascha Wildner print_otag(h, TAG_SPAN, "c", "Lb");
147754ba9607SSascha Wildner return 1;
147880387638SSascha Wildner }
147980387638SSascha Wildner
148080387638SSascha Wildner static int
mdoc__x_pre(MDOC_ARGS)148180387638SSascha Wildner mdoc__x_pre(MDOC_ARGS)
148280387638SSascha Wildner {
1483*99db7d0eSSascha Wildner struct roff_node *nn;
148454ba9607SSascha Wildner const char *cattr;
148580387638SSascha Wildner enum htmltag t;
148680387638SSascha Wildner
148780387638SSascha Wildner t = TAG_SPAN;
148880387638SSascha Wildner
148980387638SSascha Wildner switch (n->tok) {
1490070c62a6SFranco Fichtner case MDOC__A:
149154ba9607SSascha Wildner cattr = "RsA";
1492*99db7d0eSSascha Wildner if ((nn = roff_node_prev(n)) != NULL && nn->tok == MDOC__A &&
1493*99db7d0eSSascha Wildner ((nn = roff_node_next(n)) == NULL || nn->tok != MDOC__A))
149480387638SSascha Wildner print_text(h, "and");
149580387638SSascha Wildner break;
1496070c62a6SFranco Fichtner case MDOC__B:
149780387638SSascha Wildner t = TAG_I;
149854ba9607SSascha Wildner cattr = "RsB";
149980387638SSascha Wildner break;
1500070c62a6SFranco Fichtner case MDOC__C:
150154ba9607SSascha Wildner cattr = "RsC";
150280387638SSascha Wildner break;
1503070c62a6SFranco Fichtner case MDOC__D:
150454ba9607SSascha Wildner cattr = "RsD";
150580387638SSascha Wildner break;
1506070c62a6SFranco Fichtner case MDOC__I:
150780387638SSascha Wildner t = TAG_I;
150854ba9607SSascha Wildner cattr = "RsI";
150980387638SSascha Wildner break;
1510070c62a6SFranco Fichtner case MDOC__J:
151180387638SSascha Wildner t = TAG_I;
151254ba9607SSascha Wildner cattr = "RsJ";
151380387638SSascha Wildner break;
1514070c62a6SFranco Fichtner case MDOC__N:
151554ba9607SSascha Wildner cattr = "RsN";
151680387638SSascha Wildner break;
1517070c62a6SFranco Fichtner case MDOC__O:
151854ba9607SSascha Wildner cattr = "RsO";
151980387638SSascha Wildner break;
1520070c62a6SFranco Fichtner case MDOC__P:
152154ba9607SSascha Wildner cattr = "RsP";
152280387638SSascha Wildner break;
1523070c62a6SFranco Fichtner case MDOC__Q:
152454ba9607SSascha Wildner cattr = "RsQ";
152580387638SSascha Wildner break;
1526070c62a6SFranco Fichtner case MDOC__R:
152754ba9607SSascha Wildner cattr = "RsR";
152880387638SSascha Wildner break;
1529070c62a6SFranco Fichtner case MDOC__T:
153054ba9607SSascha Wildner cattr = "RsT";
153180387638SSascha Wildner break;
1532070c62a6SFranco Fichtner case MDOC__U:
153354ba9607SSascha Wildner print_otag(h, TAG_A, "ch", "RsU", n->child->string);
153454ba9607SSascha Wildner return 1;
1535070c62a6SFranco Fichtner case MDOC__V:
153654ba9607SSascha Wildner cattr = "RsV";
153780387638SSascha Wildner break;
153880387638SSascha Wildner default:
153980387638SSascha Wildner abort();
154080387638SSascha Wildner }
154180387638SSascha Wildner
154254ba9607SSascha Wildner print_otag(h, t, "c", cattr);
154354ba9607SSascha Wildner return 1;
154480387638SSascha Wildner }
154580387638SSascha Wildner
154680387638SSascha Wildner static void
mdoc__x_post(MDOC_ARGS)154780387638SSascha Wildner mdoc__x_post(MDOC_ARGS)
154880387638SSascha Wildner {
1549*99db7d0eSSascha Wildner struct roff_node *nn;
155080387638SSascha Wildner
1551*99db7d0eSSascha Wildner if (n->tok == MDOC__A &&
1552*99db7d0eSSascha Wildner (nn = roff_node_next(n)) != NULL && nn->tok == MDOC__A &&
1553*99db7d0eSSascha Wildner ((nn = roff_node_next(nn)) == NULL || nn->tok != MDOC__A) &&
1554*99db7d0eSSascha Wildner ((nn = roff_node_prev(n)) == NULL || nn->tok != MDOC__A))
155580387638SSascha Wildner return;
155680387638SSascha Wildner
155780387638SSascha Wildner /* TODO: %U */
155880387638SSascha Wildner
1559*99db7d0eSSascha Wildner if (n->parent == NULL || n->parent->tok != MDOC_Rs)
156080387638SSascha Wildner return;
156180387638SSascha Wildner
156260e1e752SSascha Wildner h->flags |= HTML_NOSPACE;
1563*99db7d0eSSascha Wildner print_text(h, roff_node_next(n) ? "," : ".");
156480387638SSascha Wildner }
156580387638SSascha Wildner
156680387638SSascha Wildner static int
mdoc_bk_pre(MDOC_ARGS)156780387638SSascha Wildner mdoc_bk_pre(MDOC_ARGS)
156880387638SSascha Wildner {
156980387638SSascha Wildner
157080387638SSascha Wildner switch (n->type) {
157154ba9607SSascha Wildner case ROFFT_BLOCK:
157280387638SSascha Wildner break;
157354ba9607SSascha Wildner case ROFFT_HEAD:
157454ba9607SSascha Wildner return 0;
157554ba9607SSascha Wildner case ROFFT_BODY:
157654ba9607SSascha Wildner if (n->parent->args != NULL || n->prev->child == NULL)
157780387638SSascha Wildner h->flags |= HTML_PREKEEP;
157880387638SSascha Wildner break;
157980387638SSascha Wildner default:
158080387638SSascha Wildner abort();
158180387638SSascha Wildner }
158280387638SSascha Wildner
158354ba9607SSascha Wildner return 1;
158480387638SSascha Wildner }
158580387638SSascha Wildner
158680387638SSascha Wildner static void
mdoc_bk_post(MDOC_ARGS)158780387638SSascha Wildner mdoc_bk_post(MDOC_ARGS)
158880387638SSascha Wildner {
158980387638SSascha Wildner
159054ba9607SSascha Wildner if (n->type == ROFFT_BODY)
159180387638SSascha Wildner h->flags &= ~(HTML_KEEP | HTML_PREKEEP);
159280387638SSascha Wildner }
159380387638SSascha Wildner
159480387638SSascha Wildner static int
mdoc_quote_pre(MDOC_ARGS)159580387638SSascha Wildner mdoc_quote_pre(MDOC_ARGS)
159680387638SSascha Wildner {
159754ba9607SSascha Wildner if (n->type != ROFFT_BODY)
159854ba9607SSascha Wildner return 1;
159980387638SSascha Wildner
160080387638SSascha Wildner switch (n->tok) {
1601070c62a6SFranco Fichtner case MDOC_Ao:
1602070c62a6SFranco Fichtner case MDOC_Aq:
160354ba9607SSascha Wildner print_text(h, n->child != NULL && n->child->next == NULL &&
160454ba9607SSascha Wildner n->child->tok == MDOC_Mt ? "<" : "\\(la");
160580387638SSascha Wildner break;
1606070c62a6SFranco Fichtner case MDOC_Bro:
1607070c62a6SFranco Fichtner case MDOC_Brq:
160880387638SSascha Wildner print_text(h, "\\(lC");
160980387638SSascha Wildner break;
1610070c62a6SFranco Fichtner case MDOC_Bo:
1611070c62a6SFranco Fichtner case MDOC_Bq:
161280387638SSascha Wildner print_text(h, "\\(lB");
161380387638SSascha Wildner break;
1614070c62a6SFranco Fichtner case MDOC_Oo:
1615070c62a6SFranco Fichtner case MDOC_Op:
161680387638SSascha Wildner print_text(h, "\\(lB");
161754ba9607SSascha Wildner /*
161854ba9607SSascha Wildner * Give up on semantic markup for now.
161954ba9607SSascha Wildner * We cannot use TAG_SPAN because .Oo may contain blocks.
1620*99db7d0eSSascha Wildner * We cannot use TAG_DIV because we might be in a
162154ba9607SSascha Wildner * phrasing context (like .Dl or .Pp); we cannot
162254ba9607SSascha Wildner * close out a .Pp at this point either because
162354ba9607SSascha Wildner * that would break the line.
162454ba9607SSascha Wildner */
162554ba9607SSascha Wildner /* XXX print_otag(h, TAG_???, "c", "Op"); */
162680387638SSascha Wildner break;
1627070c62a6SFranco Fichtner case MDOC_En:
1628070c62a6SFranco Fichtner if (NULL == n->norm->Es ||
1629070c62a6SFranco Fichtner NULL == n->norm->Es->child)
163054ba9607SSascha Wildner return 1;
1631070c62a6SFranco Fichtner print_text(h, n->norm->Es->child->string);
163236342e81SSascha Wildner break;
1633070c62a6SFranco Fichtner case MDOC_Do:
1634070c62a6SFranco Fichtner case MDOC_Dq:
1635*99db7d0eSSascha Wildner print_text(h, "\\(lq");
1636*99db7d0eSSascha Wildner break;
1637070c62a6SFranco Fichtner case MDOC_Qo:
1638070c62a6SFranco Fichtner case MDOC_Qq:
1639*99db7d0eSSascha Wildner print_text(h, "\"");
164080387638SSascha Wildner break;
1641070c62a6SFranco Fichtner case MDOC_Po:
1642070c62a6SFranco Fichtner case MDOC_Pq:
164380387638SSascha Wildner print_text(h, "(");
164480387638SSascha Wildner break;
1645070c62a6SFranco Fichtner case MDOC_Ql:
164636342e81SSascha Wildner print_text(h, "\\(oq");
164736342e81SSascha Wildner h->flags |= HTML_NOSPACE;
164854ba9607SSascha Wildner print_otag(h, TAG_CODE, "c", "Li");
164936342e81SSascha Wildner break;
1650070c62a6SFranco Fichtner case MDOC_So:
1651070c62a6SFranco Fichtner case MDOC_Sq:
165280387638SSascha Wildner print_text(h, "\\(oq");
165380387638SSascha Wildner break;
165480387638SSascha Wildner default:
165580387638SSascha Wildner abort();
165680387638SSascha Wildner }
165780387638SSascha Wildner
165880387638SSascha Wildner h->flags |= HTML_NOSPACE;
165954ba9607SSascha Wildner return 1;
166080387638SSascha Wildner }
166180387638SSascha Wildner
166280387638SSascha Wildner static void
mdoc_quote_post(MDOC_ARGS)166380387638SSascha Wildner mdoc_quote_post(MDOC_ARGS)
166480387638SSascha Wildner {
166580387638SSascha Wildner
166654ba9607SSascha Wildner if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM)
166780387638SSascha Wildner return;
166880387638SSascha Wildner
166980387638SSascha Wildner h->flags |= HTML_NOSPACE;
167080387638SSascha Wildner
167180387638SSascha Wildner switch (n->tok) {
1672070c62a6SFranco Fichtner case MDOC_Ao:
1673070c62a6SFranco Fichtner case MDOC_Aq:
167454ba9607SSascha Wildner print_text(h, n->child != NULL && n->child->next == NULL &&
167554ba9607SSascha Wildner n->child->tok == MDOC_Mt ? ">" : "\\(ra");
167680387638SSascha Wildner break;
1677070c62a6SFranco Fichtner case MDOC_Bro:
1678070c62a6SFranco Fichtner case MDOC_Brq:
167980387638SSascha Wildner print_text(h, "\\(rC");
168080387638SSascha Wildner break;
1681070c62a6SFranco Fichtner case MDOC_Oo:
1682070c62a6SFranco Fichtner case MDOC_Op:
1683070c62a6SFranco Fichtner case MDOC_Bo:
1684070c62a6SFranco Fichtner case MDOC_Bq:
168580387638SSascha Wildner print_text(h, "\\(rB");
168680387638SSascha Wildner break;
1687070c62a6SFranco Fichtner case MDOC_En:
168854ba9607SSascha Wildner if (n->norm->Es == NULL ||
168954ba9607SSascha Wildner n->norm->Es->child == NULL ||
169054ba9607SSascha Wildner n->norm->Es->child->next == NULL)
169154ba9607SSascha Wildner h->flags &= ~HTML_NOSPACE;
169254ba9607SSascha Wildner else
1693070c62a6SFranco Fichtner print_text(h, n->norm->Es->child->next->string);
1694070c62a6SFranco Fichtner break;
1695070c62a6SFranco Fichtner case MDOC_Do:
1696070c62a6SFranco Fichtner case MDOC_Dq:
169780387638SSascha Wildner print_text(h, "\\(rq");
169880387638SSascha Wildner break;
1699*99db7d0eSSascha Wildner case MDOC_Qo:
1700*99db7d0eSSascha Wildner case MDOC_Qq:
1701*99db7d0eSSascha Wildner print_text(h, "\"");
1702*99db7d0eSSascha Wildner break;
1703070c62a6SFranco Fichtner case MDOC_Po:
1704070c62a6SFranco Fichtner case MDOC_Pq:
170580387638SSascha Wildner print_text(h, ")");
170680387638SSascha Wildner break;
1707070c62a6SFranco Fichtner case MDOC_Ql:
1708070c62a6SFranco Fichtner case MDOC_So:
1709070c62a6SFranco Fichtner case MDOC_Sq:
1710f88b6c16SFranco Fichtner print_text(h, "\\(cq");
171180387638SSascha Wildner break;
171280387638SSascha Wildner default:
171380387638SSascha Wildner abort();
171480387638SSascha Wildner }
171580387638SSascha Wildner }
171654ba9607SSascha Wildner
171754ba9607SSascha Wildner static int
mdoc_eo_pre(MDOC_ARGS)171854ba9607SSascha Wildner mdoc_eo_pre(MDOC_ARGS)
171954ba9607SSascha Wildner {
172054ba9607SSascha Wildner
172154ba9607SSascha Wildner if (n->type != ROFFT_BODY)
172254ba9607SSascha Wildner return 1;
172354ba9607SSascha Wildner
172454ba9607SSascha Wildner if (n->end == ENDBODY_NOT &&
172554ba9607SSascha Wildner n->parent->head->child == NULL &&
172654ba9607SSascha Wildner n->child != NULL &&
172754ba9607SSascha Wildner n->child->end != ENDBODY_NOT)
172854ba9607SSascha Wildner print_text(h, "\\&");
172954ba9607SSascha Wildner else if (n->end != ENDBODY_NOT ? n->child != NULL :
173054ba9607SSascha Wildner n->parent->head->child != NULL && (n->child != NULL ||
173154ba9607SSascha Wildner (n->parent->tail != NULL && n->parent->tail->child != NULL)))
173254ba9607SSascha Wildner h->flags |= HTML_NOSPACE;
173354ba9607SSascha Wildner return 1;
173454ba9607SSascha Wildner }
173554ba9607SSascha Wildner
173654ba9607SSascha Wildner static void
mdoc_eo_post(MDOC_ARGS)173754ba9607SSascha Wildner mdoc_eo_post(MDOC_ARGS)
173854ba9607SSascha Wildner {
173954ba9607SSascha Wildner int body, tail;
174054ba9607SSascha Wildner
174154ba9607SSascha Wildner if (n->type != ROFFT_BODY)
174254ba9607SSascha Wildner return;
174354ba9607SSascha Wildner
174454ba9607SSascha Wildner if (n->end != ENDBODY_NOT) {
174554ba9607SSascha Wildner h->flags &= ~HTML_NOSPACE;
174654ba9607SSascha Wildner return;
174754ba9607SSascha Wildner }
174854ba9607SSascha Wildner
174954ba9607SSascha Wildner body = n->child != NULL || n->parent->head->child != NULL;
175054ba9607SSascha Wildner tail = n->parent->tail != NULL && n->parent->tail->child != NULL;
175154ba9607SSascha Wildner
175254ba9607SSascha Wildner if (body && tail)
175354ba9607SSascha Wildner h->flags |= HTML_NOSPACE;
175454ba9607SSascha Wildner else if ( ! tail)
175554ba9607SSascha Wildner h->flags &= ~HTML_NOSPACE;
175654ba9607SSascha Wildner }
175754ba9607SSascha Wildner
175854ba9607SSascha Wildner static int
mdoc_abort_pre(MDOC_ARGS)175954ba9607SSascha Wildner mdoc_abort_pre(MDOC_ARGS)
176054ba9607SSascha Wildner {
176154ba9607SSascha Wildner abort();
176254ba9607SSascha Wildner }
1763