Annotation of mandoc/mdoc_html.c, Revision 1.47
1.47 ! kristaps 1: /* $Id: mdoc_html.c,v 1.46 2009/10/31 08:34:12 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #include <sys/types.h>
1.7 kristaps 18: #include <sys/param.h>
1.1 kristaps 19:
20: #include <assert.h>
21: #include <ctype.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include <unistd.h>
26:
1.23 kristaps 27: #include "out.h"
1.1 kristaps 28: #include "html.h"
29: #include "mdoc.h"
1.29 kristaps 30: #include "main.h"
1.1 kristaps 31:
32: #define INDENT 5
33: #define HALFINDENT 3
34:
35: #define MDOC_ARGS const struct mdoc_meta *m, \
36: const struct mdoc_node *n, \
37: struct html *h
38:
39: struct htmlmdoc {
40: int (*pre)(MDOC_ARGS);
41: void (*post)(MDOC_ARGS);
42: };
43:
44: static void print_mdoc(MDOC_ARGS);
45: static void print_mdoc_head(MDOC_ARGS);
46: static void print_mdoc_node(MDOC_ARGS);
47: static void print_mdoc_nodelist(MDOC_ARGS);
48:
1.23 kristaps 49: static void a2width(const char *, struct roffsu *);
50: static void a2offs(const char *, struct roffsu *);
1.27 kristaps 51:
1.1 kristaps 52: static int a2list(const struct mdoc_node *);
53:
54: static void mdoc_root_post(MDOC_ARGS);
55: static int mdoc_root_pre(MDOC_ARGS);
56:
1.10 kristaps 57: static void mdoc__x_post(MDOC_ARGS);
58: static int mdoc__x_pre(MDOC_ARGS);
1.1 kristaps 59: static int mdoc_ad_pre(MDOC_ARGS);
60: static int mdoc_an_pre(MDOC_ARGS);
1.5 kristaps 61: static int mdoc_ap_pre(MDOC_ARGS);
1.1 kristaps 62: static void mdoc_aq_post(MDOC_ARGS);
63: static int mdoc_aq_pre(MDOC_ARGS);
64: static int mdoc_ar_pre(MDOC_ARGS);
65: static int mdoc_bd_pre(MDOC_ARGS);
1.5 kristaps 66: static int mdoc_bf_pre(MDOC_ARGS);
1.1 kristaps 67: static void mdoc_bl_post(MDOC_ARGS);
68: static int mdoc_bl_pre(MDOC_ARGS);
1.4 kristaps 69: static void mdoc_bq_post(MDOC_ARGS);
70: static int mdoc_bq_pre(MDOC_ARGS);
1.2 kristaps 71: static void mdoc_brq_post(MDOC_ARGS);
72: static int mdoc_brq_pre(MDOC_ARGS);
1.6 kristaps 73: static int mdoc_bt_pre(MDOC_ARGS);
1.4 kristaps 74: static int mdoc_bx_pre(MDOC_ARGS);
1.1 kristaps 75: static int mdoc_cd_pre(MDOC_ARGS);
76: static int mdoc_d1_pre(MDOC_ARGS);
77: static void mdoc_dq_post(MDOC_ARGS);
78: static int mdoc_dq_pre(MDOC_ARGS);
79: static int mdoc_dv_pre(MDOC_ARGS);
80: static int mdoc_fa_pre(MDOC_ARGS);
81: static int mdoc_fd_pre(MDOC_ARGS);
82: static int mdoc_fl_pre(MDOC_ARGS);
83: static int mdoc_fn_pre(MDOC_ARGS);
84: static int mdoc_ft_pre(MDOC_ARGS);
85: static int mdoc_em_pre(MDOC_ARGS);
86: static int mdoc_er_pre(MDOC_ARGS);
87: static int mdoc_ev_pre(MDOC_ARGS);
88: static int mdoc_ex_pre(MDOC_ARGS);
1.4 kristaps 89: static void mdoc_fo_post(MDOC_ARGS);
90: static int mdoc_fo_pre(MDOC_ARGS);
91: static int mdoc_ic_pre(MDOC_ARGS);
92: static int mdoc_in_pre(MDOC_ARGS);
1.27 kristaps 93: static int mdoc_it_block_pre(MDOC_ARGS, int, int,
94: struct roffsu *, struct roffsu *);
95: static int mdoc_it_head_pre(MDOC_ARGS, int,
96: struct roffsu *);
97: static int mdoc_it_body_pre(MDOC_ARGS, int);
1.1 kristaps 98: static int mdoc_it_pre(MDOC_ARGS);
1.6 kristaps 99: static int mdoc_lb_pre(MDOC_ARGS);
100: static int mdoc_li_pre(MDOC_ARGS);
1.2 kristaps 101: static int mdoc_lk_pre(MDOC_ARGS);
102: static int mdoc_mt_pre(MDOC_ARGS);
1.5 kristaps 103: static int mdoc_ms_pre(MDOC_ARGS);
1.1 kristaps 104: static int mdoc_nd_pre(MDOC_ARGS);
105: static int mdoc_nm_pre(MDOC_ARGS);
106: static int mdoc_ns_pre(MDOC_ARGS);
107: static void mdoc_op_post(MDOC_ARGS);
108: static int mdoc_op_pre(MDOC_ARGS);
109: static int mdoc_pa_pre(MDOC_ARGS);
1.5 kristaps 110: static void mdoc_pf_post(MDOC_ARGS);
111: static int mdoc_pf_pre(MDOC_ARGS);
1.1 kristaps 112: static void mdoc_pq_post(MDOC_ARGS);
113: static int mdoc_pq_pre(MDOC_ARGS);
1.5 kristaps 114: static int mdoc_rs_pre(MDOC_ARGS);
1.4 kristaps 115: static int mdoc_rv_pre(MDOC_ARGS);
1.1 kristaps 116: static int mdoc_sh_pre(MDOC_ARGS);
117: static int mdoc_sp_pre(MDOC_ARGS);
118: static void mdoc_sq_post(MDOC_ARGS);
119: static int mdoc_sq_pre(MDOC_ARGS);
120: static int mdoc_ss_pre(MDOC_ARGS);
121: static int mdoc_sx_pre(MDOC_ARGS);
1.6 kristaps 122: static int mdoc_sy_pre(MDOC_ARGS);
123: static int mdoc_ud_pre(MDOC_ARGS);
1.4 kristaps 124: static int mdoc_va_pre(MDOC_ARGS);
1.1 kristaps 125: static int mdoc_vt_pre(MDOC_ARGS);
126: static int mdoc_xr_pre(MDOC_ARGS);
127: static int mdoc_xx_pre(MDOC_ARGS);
128:
129: #ifdef __linux__
130: extern size_t strlcpy(char *, const char *, size_t);
131: extern size_t strlcat(char *, const char *, size_t);
132: #endif
133:
134: static const struct htmlmdoc mdocs[MDOC_MAX] = {
1.5 kristaps 135: {mdoc_ap_pre, NULL}, /* Ap */
1.1 kristaps 136: {NULL, NULL}, /* Dd */
137: {NULL, NULL}, /* Dt */
138: {NULL, NULL}, /* Os */
139: {mdoc_sh_pre, NULL }, /* Sh */
140: {mdoc_ss_pre, NULL }, /* Ss */
141: {mdoc_sp_pre, NULL}, /* Pp */
142: {mdoc_d1_pre, NULL}, /* D1 */
143: {mdoc_d1_pre, NULL}, /* Dl */
144: {mdoc_bd_pre, NULL}, /* Bd */
145: {NULL, NULL}, /* Ed */
146: {mdoc_bl_pre, mdoc_bl_post}, /* Bl */
147: {NULL, NULL}, /* El */
148: {mdoc_it_pre, NULL}, /* It */
149: {mdoc_ad_pre, NULL}, /* Ad */
150: {mdoc_an_pre, NULL}, /* An */
151: {mdoc_ar_pre, NULL}, /* Ar */
152: {mdoc_cd_pre, NULL}, /* Cd */
153: {mdoc_fl_pre, NULL}, /* Cm */
154: {mdoc_dv_pre, NULL}, /* Dv */
155: {mdoc_er_pre, NULL}, /* Er */
156: {mdoc_ev_pre, NULL}, /* Ev */
157: {mdoc_ex_pre, NULL}, /* Ex */
158: {mdoc_fa_pre, NULL}, /* Fa */
159: {mdoc_fd_pre, NULL}, /* Fd */
160: {mdoc_fl_pre, NULL}, /* Fl */
161: {mdoc_fn_pre, NULL}, /* Fn */
162: {mdoc_ft_pre, NULL}, /* Ft */
1.4 kristaps 163: {mdoc_ic_pre, NULL}, /* Ic */
164: {mdoc_in_pre, NULL}, /* In */
1.6 kristaps 165: {mdoc_li_pre, NULL}, /* Li */
1.1 kristaps 166: {mdoc_nd_pre, NULL}, /* Nd */
167: {mdoc_nm_pre, NULL}, /* Nm */
168: {mdoc_op_pre, mdoc_op_post}, /* Op */
169: {NULL, NULL}, /* Ot */
170: {mdoc_pa_pre, NULL}, /* Pa */
1.4 kristaps 171: {mdoc_rv_pre, NULL}, /* Rv */
1.1 kristaps 172: {NULL, NULL}, /* St */
1.4 kristaps 173: {mdoc_va_pre, NULL}, /* Va */
1.1 kristaps 174: {mdoc_vt_pre, NULL}, /* Vt */
175: {mdoc_xr_pre, NULL}, /* Xr */
1.10 kristaps 176: {mdoc__x_pre, mdoc__x_post}, /* %A */
177: {mdoc__x_pre, mdoc__x_post}, /* %B */
178: {mdoc__x_pre, mdoc__x_post}, /* %D */
179: {mdoc__x_pre, mdoc__x_post}, /* %I */
180: {mdoc__x_pre, mdoc__x_post}, /* %J */
181: {mdoc__x_pre, mdoc__x_post}, /* %N */
182: {mdoc__x_pre, mdoc__x_post}, /* %O */
183: {mdoc__x_pre, mdoc__x_post}, /* %P */
184: {mdoc__x_pre, mdoc__x_post}, /* %R */
185: {mdoc__x_pre, mdoc__x_post}, /* %T */
186: {mdoc__x_pre, mdoc__x_post}, /* %V */
1.1 kristaps 187: {NULL, NULL}, /* Ac */
188: {mdoc_aq_pre, mdoc_aq_post}, /* Ao */
189: {mdoc_aq_pre, mdoc_aq_post}, /* Aq */
190: {NULL, NULL}, /* At */
191: {NULL, NULL}, /* Bc */
1.5 kristaps 192: {mdoc_bf_pre, NULL}, /* Bf */
1.4 kristaps 193: {mdoc_bq_pre, mdoc_bq_post}, /* Bo */
194: {mdoc_bq_pre, mdoc_bq_post}, /* Bq */
1.1 kristaps 195: {mdoc_xx_pre, NULL}, /* Bsx */
1.4 kristaps 196: {mdoc_bx_pre, NULL}, /* Bx */
1.1 kristaps 197: {NULL, NULL}, /* Db */
198: {NULL, NULL}, /* Dc */
1.4 kristaps 199: {mdoc_dq_pre, mdoc_dq_post}, /* Do */
1.1 kristaps 200: {mdoc_dq_pre, mdoc_dq_post}, /* Dq */
201: {NULL, NULL}, /* Ec */
202: {NULL, NULL}, /* Ef */
203: {mdoc_em_pre, NULL}, /* Em */
204: {NULL, NULL}, /* Eo */
205: {mdoc_xx_pre, NULL}, /* Fx */
1.5 kristaps 206: {mdoc_ms_pre, NULL}, /* Ms */ /* FIXME: convert to symbol? */
1.1 kristaps 207: {NULL, NULL}, /* No */
208: {mdoc_ns_pre, NULL}, /* Ns */
209: {mdoc_xx_pre, NULL}, /* Nx */
210: {mdoc_xx_pre, NULL}, /* Ox */
211: {NULL, NULL}, /* Pc */
1.5 kristaps 212: {mdoc_pf_pre, mdoc_pf_post}, /* Pf */
1.1 kristaps 213: {mdoc_pq_pre, mdoc_pq_post}, /* Po */
214: {mdoc_pq_pre, mdoc_pq_post}, /* Pq */
215: {NULL, NULL}, /* Qc */
1.4 kristaps 216: {mdoc_sq_pre, mdoc_sq_post}, /* Ql */
1.5 kristaps 217: {mdoc_dq_pre, mdoc_dq_post}, /* Qo */
218: {mdoc_dq_pre, mdoc_dq_post}, /* Qq */
1.1 kristaps 219: {NULL, NULL}, /* Re */
1.5 kristaps 220: {mdoc_rs_pre, NULL}, /* Rs */
1.1 kristaps 221: {NULL, NULL}, /* Sc */
222: {mdoc_sq_pre, mdoc_sq_post}, /* So */
223: {mdoc_sq_pre, mdoc_sq_post}, /* Sq */
1.6 kristaps 224: {NULL, NULL}, /* Sm */ /* FIXME - no idea. */
1.1 kristaps 225: {mdoc_sx_pre, NULL}, /* Sx */
1.6 kristaps 226: {mdoc_sy_pre, NULL}, /* Sy */
1.1 kristaps 227: {NULL, NULL}, /* Tn */
228: {mdoc_xx_pre, NULL}, /* Ux */
229: {NULL, NULL}, /* Xc */
230: {NULL, NULL}, /* Xo */
1.4 kristaps 231: {mdoc_fo_pre, mdoc_fo_post}, /* Fo */
1.1 kristaps 232: {NULL, NULL}, /* Fc */
1.4 kristaps 233: {mdoc_op_pre, mdoc_op_post}, /* Oo */
1.1 kristaps 234: {NULL, NULL}, /* Oc */
235: {NULL, NULL}, /* Bk */
236: {NULL, NULL}, /* Ek */
1.6 kristaps 237: {mdoc_bt_pre, NULL}, /* Bt */
1.1 kristaps 238: {NULL, NULL}, /* Hf */
239: {NULL, NULL}, /* Fr */
1.6 kristaps 240: {mdoc_ud_pre, NULL}, /* Ud */
241: {mdoc_lb_pre, NULL}, /* Lb */
1.1 kristaps 242: {mdoc_sp_pre, NULL}, /* Lp */
1.2 kristaps 243: {mdoc_lk_pre, NULL}, /* Lk */
244: {mdoc_mt_pre, NULL}, /* Mt */
245: {mdoc_brq_pre, mdoc_brq_post}, /* Brq */
246: {mdoc_brq_pre, mdoc_brq_post}, /* Bro */
1.1 kristaps 247: {NULL, NULL}, /* Brc */
1.10 kristaps 248: {mdoc__x_pre, mdoc__x_post}, /* %C */
1.2 kristaps 249: {NULL, NULL}, /* Es */ /* TODO */
250: {NULL, NULL}, /* En */ /* TODO */
1.1 kristaps 251: {mdoc_xx_pre, NULL}, /* Dx */
1.10 kristaps 252: {mdoc__x_pre, mdoc__x_post}, /* %Q */
1.1 kristaps 253: {mdoc_sp_pre, NULL}, /* br */
254: {mdoc_sp_pre, NULL}, /* sp */
1.37 kristaps 255: {mdoc__x_pre, mdoc__x_post}, /* %U */
1.1 kristaps 256: };
257:
258:
259: void
260: html_mdoc(void *arg, const struct mdoc *m)
261: {
262: struct html *h;
263: struct tag *t;
264:
265: h = (struct html *)arg;
266:
267: print_gen_doctype(h);
268: t = print_otag(h, TAG_HTML, 0, NULL);
269: print_mdoc(mdoc_meta(m), mdoc_node(m), h);
270: print_tagq(h, t);
271:
272: printf("\n");
273: }
274:
275:
1.23 kristaps 276: /*
277: * Return the list type for `Bl', e.g., `Bl -column' returns
278: * MDOC_Column. This can ONLY be run for lists; it will abort() if no
279: * list type is found.
280: */
1.1 kristaps 281: static int
282: a2list(const struct mdoc_node *n)
283: {
284: int i;
285:
286: assert(n->args);
287: for (i = 0; i < (int)n->args->argc; i++)
288: switch (n->args->argv[i].arg) {
289: case (MDOC_Enum):
290: /* FALLTHROUGH */
291: case (MDOC_Dash):
292: /* FALLTHROUGH */
293: case (MDOC_Hyphen):
294: /* FALLTHROUGH */
295: case (MDOC_Bullet):
296: /* FALLTHROUGH */
297: case (MDOC_Tag):
298: /* FALLTHROUGH */
299: case (MDOC_Hang):
300: /* FALLTHROUGH */
301: case (MDOC_Inset):
302: /* FALLTHROUGH */
303: case (MDOC_Diag):
304: /* FALLTHROUGH */
305: case (MDOC_Item):
306: /* FALLTHROUGH */
307: case (MDOC_Column):
308: /* FALLTHROUGH */
309: case (MDOC_Ohang):
310: return(n->args->argv[i].arg);
311: default:
312: break;
313: }
314:
315: abort();
316: /* NOTREACHED */
317: }
318:
319:
1.23 kristaps 320: /*
321: * Calculate the scaling unit passed in a `-width' argument. This uses
322: * either a native scaling unit (e.g., 1i, 2m) or the string length of
323: * the value.
324: */
325: static void
326: a2width(const char *p, struct roffsu *su)
1.1 kristaps 327: {
328:
1.32 kristaps 329: if ( ! a2roffsu(p, su, SCALE_MAX)) {
330: su->unit = SCALE_EM;
331: su->scale = (int)strlen(p);
332: }
1.1 kristaps 333: }
334:
335:
1.23 kristaps 336: /*
337: * Calculate the scaling unit passed in an `-offset' argument. This
338: * uses either a native scaling unit (e.g., 1i, 2m), one of a set of
339: * predefined strings (indent, etc.), or the string length of the value.
340: */
341: static void
342: a2offs(const char *p, struct roffsu *su)
1.1 kristaps 343: {
344:
1.31 kristaps 345: /* FIXME: "right"? */
346:
1.1 kristaps 347: if (0 == strcmp(p, "left"))
1.23 kristaps 348: SCALE_HS_INIT(su, 0);
349: else if (0 == strcmp(p, "indent"))
350: SCALE_HS_INIT(su, INDENT);
351: else if (0 == strcmp(p, "indent-two"))
352: SCALE_HS_INIT(su, INDENT * 2);
1.32 kristaps 353: else if ( ! a2roffsu(p, su, SCALE_MAX)) {
1.24 kristaps 354: su->unit = SCALE_EM;
355: su->scale = (int)strlen(p);
356: }
1.1 kristaps 357: }
358:
359:
360: static void
361: print_mdoc(MDOC_ARGS)
362: {
363: struct tag *t;
364: struct htmlpair tag;
365:
366: t = print_otag(h, TAG_HEAD, 0, NULL);
367: print_mdoc_head(m, n, h);
368: print_tagq(h, t);
369:
370: t = print_otag(h, TAG_BODY, 0, NULL);
371:
372: tag.key = ATTR_CLASS;
373: tag.val = "body";
374: print_otag(h, TAG_DIV, 1, &tag);
375:
376: print_mdoc_nodelist(m, n, h);
377: print_tagq(h, t);
378: }
379:
380:
381: /* ARGSUSED */
382: static void
383: print_mdoc_head(MDOC_ARGS)
384: {
385:
386: print_gen_head(h);
1.20 kristaps 387: bufinit(h);
388: buffmt(h, "%s(%d)", m->title, m->msec);
1.1 kristaps 389:
390: if (m->arch) {
1.20 kristaps 391: bufcat(h, " (");
392: bufcat(h, m->arch);
393: bufcat(h, ")");
1.1 kristaps 394: }
395:
396: print_otag(h, TAG_TITLE, 0, NULL);
1.20 kristaps 397: print_text(h, h->buf);
1.1 kristaps 398: }
399:
400:
401: static void
402: print_mdoc_nodelist(MDOC_ARGS)
403: {
404:
405: print_mdoc_node(m, n, h);
406: if (n->next)
407: print_mdoc_nodelist(m, n->next, h);
408: }
409:
410:
411: static void
412: print_mdoc_node(MDOC_ARGS)
413: {
414: int child;
415: struct tag *t;
416:
417: child = 1;
1.39 kristaps 418: t = h->tags.head;
1.1 kristaps 419:
1.16 kristaps 420: bufinit(h);
1.1 kristaps 421: switch (n->type) {
422: case (MDOC_ROOT):
423: child = mdoc_root_pre(m, n, h);
424: break;
425: case (MDOC_TEXT):
426: print_text(h, n->string);
427: break;
428: default:
429: if (mdocs[n->tok].pre)
430: child = (*mdocs[n->tok].pre)(m, n, h);
431: break;
432: }
433:
434: if (child && n->child)
435: print_mdoc_nodelist(m, n->child, h);
436:
437: print_stagq(h, t);
438:
1.16 kristaps 439: bufinit(h);
1.1 kristaps 440: switch (n->type) {
441: case (MDOC_ROOT):
442: mdoc_root_post(m, n, h);
443: break;
444: case (MDOC_TEXT):
445: break;
446: default:
447: if (mdocs[n->tok].post)
448: (*mdocs[n->tok].post)(m, n, h);
449: break;
450: }
451: }
452:
453:
454: /* ARGSUSED */
455: static void
456: mdoc_root_post(MDOC_ARGS)
457: {
1.40 kristaps 458: struct htmlpair tag[3];
1.1 kristaps 459: struct tag *t, *tt;
1.36 kristaps 460: char b[DATESIZ];
461:
462: time2a(m->date, b, DATESIZ);
1.1 kristaps 463:
1.23 kristaps 464: /*
465: * XXX: this should use divs, but in Firefox, divs with nested
466: * divs for some reason puke when trying to put a border line
467: * below. So I use tables, instead.
468: */
469:
470: PAIR_CLASS_INIT(&tag[0], "footer");
471: bufcat_style(h, "width", "100%");
472: PAIR_STYLE_INIT(&tag[1], h);
1.40 kristaps 473: PAIR_SUMMARY_INIT(&tag[2], "footer");
474:
475: t = print_otag(h, TAG_TABLE, 3, tag);
1.1 kristaps 476: tt = print_otag(h, TAG_TR, 0, NULL);
477:
1.23 kristaps 478: bufinit(h);
479: bufcat_style(h, "width", "50%");
480: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 481: print_otag(h, TAG_TD, 1, tag);
482: print_text(h, b);
483: print_stagq(h, tt);
484:
1.23 kristaps 485: bufinit(h);
486: bufcat_style(h, "width", "50%");
487: bufcat_style(h, "text-align", "right");
488: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 489: print_otag(h, TAG_TD, 1, tag);
490: print_text(h, m->os);
491: print_tagq(h, t);
492: }
493:
494:
495: /* ARGSUSED */
496: static int
497: mdoc_root_pre(MDOC_ARGS)
498: {
1.40 kristaps 499: struct htmlpair tag[3];
1.1 kristaps 500: struct tag *t, *tt;
501: char b[BUFSIZ], title[BUFSIZ];
502:
503: (void)strlcpy(b, m->vol, BUFSIZ);
504:
505: if (m->arch) {
506: (void)strlcat(b, " (", BUFSIZ);
507: (void)strlcat(b, m->arch, BUFSIZ);
508: (void)strlcat(b, ")", BUFSIZ);
509: }
510:
511: (void)snprintf(title, BUFSIZ - 1,
512: "%s(%d)", m->title, m->msec);
513:
1.23 kristaps 514: /* XXX: see note in mdoc_root_post() about divs. */
515:
516: PAIR_CLASS_INIT(&tag[0], "header");
517: bufcat_style(h, "width", "100%");
518: PAIR_STYLE_INIT(&tag[1], h);
1.40 kristaps 519: PAIR_SUMMARY_INIT(&tag[2], "header");
520:
521: t = print_otag(h, TAG_TABLE, 3, tag);
522:
1.1 kristaps 523: tt = print_otag(h, TAG_TR, 0, NULL);
524:
1.23 kristaps 525: bufinit(h);
526: bufcat_style(h, "width", "10%");
527: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 528: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 529: print_text(h, title);
1.1 kristaps 530: print_stagq(h, tt);
531:
1.23 kristaps 532: bufinit(h);
533: bufcat_style(h, "text-align", "center");
534: bufcat_style(h, "white-space", "nowrap");
535: bufcat_style(h, "width", "80%");
536: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 537: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 538: print_text(h, b);
1.1 kristaps 539: print_stagq(h, tt);
540:
1.23 kristaps 541: bufinit(h);
542: bufcat_style(h, "text-align", "right");
543: bufcat_style(h, "width", "10%");
544: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 545: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 546: print_text(h, title);
1.1 kristaps 547: print_tagq(h, t);
548: return(1);
549: }
550:
551:
552: /* ARGSUSED */
553: static int
554: mdoc_sh_pre(MDOC_ARGS)
555: {
556: struct htmlpair tag[2];
557: const struct mdoc_node *nn;
1.41 kristaps 558: char buf[BUFSIZ];
1.23 kristaps 559: struct roffsu su;
1.21 kristaps 560:
561: if (MDOC_BODY == n->type) {
1.23 kristaps 562: SCALE_HS_INIT(&su, INDENT);
563: bufcat_su(h, "margin-left", &su);
564: PAIR_CLASS_INIT(&tag[0], "sec-body");
565: PAIR_STYLE_INIT(&tag[1], h);
1.21 kristaps 566: print_otag(h, TAG_DIV, 2, tag);
1.1 kristaps 567: return(1);
568: } else if (MDOC_BLOCK == n->type) {
1.23 kristaps 569: PAIR_CLASS_INIT(&tag[0], "sec-block");
1.1 kristaps 570: if (n->prev && NULL == n->prev->body->child) {
571: print_otag(h, TAG_DIV, 1, tag);
572: return(1);
573: }
1.23 kristaps 574:
575: SCALE_VS_INIT(&su, 1);
576: bufcat_su(h, "margin-top", &su);
1.1 kristaps 577: if (NULL == n->next)
1.23 kristaps 578: bufcat_su(h, "margin-bottom", &su);
1.1 kristaps 579:
1.23 kristaps 580: PAIR_STYLE_INIT(&tag[1], h);
1.1 kristaps 581: print_otag(h, TAG_DIV, 2, tag);
582: return(1);
583: }
584:
1.42 kristaps 585: buf[0] = '\0';
1.21 kristaps 586: for (nn = n->child; nn; nn = nn->next) {
1.41 kristaps 587: html_idcat(buf, nn->string, BUFSIZ);
1.21 kristaps 588: if (nn->next)
1.42 kristaps 589: html_idcat(buf, " ", BUFSIZ);
1.21 kristaps 590: }
591:
1.23 kristaps 592: /*
593: * TODO: make sure there are no duplicates, as HTML does not
594: * allow for multiple `id' tags of the same name.
595: */
1.22 kristaps 596:
1.23 kristaps 597: PAIR_CLASS_INIT(&tag[0], "sec-head");
1.21 kristaps 598: tag[1].key = ATTR_ID;
1.41 kristaps 599: tag[1].val = buf;
1.1 kristaps 600: print_otag(h, TAG_DIV, 2, tag);
601: return(1);
602: }
603:
604:
605: /* ARGSUSED */
606: static int
607: mdoc_ss_pre(MDOC_ARGS)
608: {
1.21 kristaps 609: struct htmlpair tag[3];
1.1 kristaps 610: const struct mdoc_node *nn;
1.41 kristaps 611: char buf[BUFSIZ];
1.23 kristaps 612: struct roffsu su;
1.1 kristaps 613:
1.23 kristaps 614: SCALE_VS_INIT(&su, 1);
1.1 kristaps 615:
616: if (MDOC_BODY == n->type) {
1.23 kristaps 617: PAIR_CLASS_INIT(&tag[0], "ssec-body");
1.1 kristaps 618: if (n->parent->next && n->child) {
1.23 kristaps 619: bufcat_su(h, "margin-bottom", &su);
620: PAIR_STYLE_INIT(&tag[1], h);
621: print_otag(h, TAG_DIV, 2, tag);
622: } else
623: print_otag(h, TAG_DIV, 1, tag);
1.1 kristaps 624: return(1);
625: } else if (MDOC_BLOCK == n->type) {
1.23 kristaps 626: PAIR_CLASS_INIT(&tag[0], "ssec-block");
1.1 kristaps 627: if (n->prev) {
1.23 kristaps 628: bufcat_su(h, "margin-top", &su);
629: PAIR_STYLE_INIT(&tag[1], h);
630: print_otag(h, TAG_DIV, 2, tag);
631: } else
632: print_otag(h, TAG_DIV, 1, tag);
1.1 kristaps 633: return(1);
634: }
635:
1.23 kristaps 636: /* TODO: see note in mdoc_sh_pre() about duplicates. */
637:
1.42 kristaps 638: buf[0] = '\0';
1.21 kristaps 639: for (nn = n->child; nn; nn = nn->next) {
1.41 kristaps 640: html_idcat(buf, nn->string, BUFSIZ);
1.21 kristaps 641: if (nn->next)
1.42 kristaps 642: html_idcat(buf, " ", BUFSIZ);
1.21 kristaps 643: }
644:
1.23 kristaps 645: SCALE_HS_INIT(&su, INDENT - HALFINDENT);
646: su.scale = -su.scale;
647: bufcat_su(h, "margin-left", &su);
1.22 kristaps 648:
1.23 kristaps 649: PAIR_CLASS_INIT(&tag[0], "ssec-head");
650: PAIR_STYLE_INIT(&tag[1], h);
1.21 kristaps 651: tag[2].key = ATTR_ID;
1.41 kristaps 652: tag[2].val = buf;
1.21 kristaps 653: print_otag(h, TAG_DIV, 3, tag);
1.1 kristaps 654: return(1);
655: }
656:
657:
658: /* ARGSUSED */
659: static int
660: mdoc_fl_pre(MDOC_ARGS)
661: {
662: struct htmlpair tag;
663:
1.23 kristaps 664: PAIR_CLASS_INIT(&tag, "flag");
1.1 kristaps 665: print_otag(h, TAG_SPAN, 1, &tag);
666: if (MDOC_Fl == n->tok) {
667: print_text(h, "\\-");
668: h->flags |= HTML_NOSPACE;
669: }
670: return(1);
671: }
672:
673:
674: /* ARGSUSED */
675: static int
676: mdoc_nd_pre(MDOC_ARGS)
677: {
678: struct htmlpair tag;
679:
680: if (MDOC_BODY != n->type)
681: return(1);
682:
1.24 kristaps 683: /* XXX: this tag in theory can contain block elements. */
684:
1.1 kristaps 685: print_text(h, "\\(em");
1.23 kristaps 686: PAIR_CLASS_INIT(&tag, "desc-body");
1.1 kristaps 687: print_otag(h, TAG_SPAN, 1, &tag);
688: return(1);
689: }
690:
691:
692: /* ARGSUSED */
693: static int
694: mdoc_op_pre(MDOC_ARGS)
695: {
696: struct htmlpair tag;
697:
698: if (MDOC_BODY != n->type)
699: return(1);
700:
1.24 kristaps 701: /* XXX: this tag in theory can contain block elements. */
702:
1.1 kristaps 703: print_text(h, "\\(lB");
704: h->flags |= HTML_NOSPACE;
1.23 kristaps 705: PAIR_CLASS_INIT(&tag, "opt");
1.1 kristaps 706: print_otag(h, TAG_SPAN, 1, &tag);
707: return(1);
708: }
709:
710:
711: /* ARGSUSED */
712: static void
713: mdoc_op_post(MDOC_ARGS)
714: {
715:
716: if (MDOC_BODY != n->type)
717: return;
718: h->flags |= HTML_NOSPACE;
719: print_text(h, "\\(rB");
720: }
721:
722:
723: static int
724: mdoc_nm_pre(MDOC_ARGS)
725: {
726: struct htmlpair tag;
727:
1.47 ! kristaps 728: if (SEC_SYNOPSIS == n->sec && n->prev) {
! 729: bufcat_style(h, "clear", "both");
! 730: PAIR_STYLE_INIT(&tag, h);
! 731: print_otag(h, TAG_BR, 1, &tag);
! 732: }
1.1 kristaps 733:
1.23 kristaps 734: PAIR_CLASS_INIT(&tag, "name");
1.1 kristaps 735: print_otag(h, TAG_SPAN, 1, &tag);
736: if (NULL == n->child)
737: print_text(h, m->name);
738:
739: return(1);
740: }
741:
742:
743: /* ARGSUSED */
744: static int
745: mdoc_xr_pre(MDOC_ARGS)
746: {
747: struct htmlpair tag[2];
748: const struct mdoc_node *nn;
1.17 kristaps 749:
1.23 kristaps 750: PAIR_CLASS_INIT(&tag[0], "link-man");
1.1 kristaps 751:
1.17 kristaps 752: if (h->base_man) {
1.23 kristaps 753: buffmt_man(h, n->child->string,
754: n->child->next ?
1.17 kristaps 755: n->child->next->string : NULL);
1.23 kristaps 756: tag[1].key = ATTR_HREF;
757: tag[1].val = h->buf;
758: print_otag(h, TAG_A, 2, tag);
759: } else
760: print_otag(h, TAG_A, 1, tag);
1.1 kristaps 761:
762: nn = n->child;
763: print_text(h, nn->string);
1.16 kristaps 764:
1.1 kristaps 765: if (NULL == (nn = nn->next))
766: return(0);
767:
768: h->flags |= HTML_NOSPACE;
769: print_text(h, "(");
770: h->flags |= HTML_NOSPACE;
771: print_text(h, nn->string);
772: h->flags |= HTML_NOSPACE;
773: print_text(h, ")");
774: return(0);
775: }
776:
777:
778: /* ARGSUSED */
779: static int
780: mdoc_ns_pre(MDOC_ARGS)
781: {
782:
783: h->flags |= HTML_NOSPACE;
784: return(1);
785: }
786:
787:
788: /* ARGSUSED */
789: static int
790: mdoc_ar_pre(MDOC_ARGS)
791: {
792: struct htmlpair tag;
793:
1.23 kristaps 794: PAIR_CLASS_INIT(&tag, "arg");
1.1 kristaps 795: print_otag(h, TAG_SPAN, 1, &tag);
796: return(1);
797: }
798:
799:
800: /* ARGSUSED */
801: static int
802: mdoc_xx_pre(MDOC_ARGS)
803: {
804: const char *pp;
805: struct htmlpair tag;
806:
807: switch (n->tok) {
808: case (MDOC_Bsx):
809: pp = "BSDI BSD/OS";
810: break;
811: case (MDOC_Dx):
1.45 kristaps 812: pp = "DragonFly";
1.1 kristaps 813: break;
814: case (MDOC_Fx):
815: pp = "FreeBSD";
816: break;
817: case (MDOC_Nx):
818: pp = "NetBSD";
819: break;
820: case (MDOC_Ox):
821: pp = "OpenBSD";
822: break;
823: case (MDOC_Ux):
824: pp = "UNIX";
825: break;
826: default:
827: return(1);
828: }
829:
1.23 kristaps 830: PAIR_CLASS_INIT(&tag, "unix");
1.1 kristaps 831: print_otag(h, TAG_SPAN, 1, &tag);
832: print_text(h, pp);
833: return(1);
834: }
835:
836:
837: /* ARGSUSED */
838: static int
1.4 kristaps 839: mdoc_bx_pre(MDOC_ARGS)
840: {
841: const struct mdoc_node *nn;
842: struct htmlpair tag;
843:
1.23 kristaps 844: PAIR_CLASS_INIT(&tag, "unix");
1.4 kristaps 845: print_otag(h, TAG_SPAN, 1, &tag);
846:
847: for (nn = n->child; nn; nn = nn->next)
848: print_mdoc_node(m, nn, h);
849:
850: if (n->child)
851: h->flags |= HTML_NOSPACE;
852:
853: print_text(h, "BSD");
854: return(0);
855: }
856:
857:
858: /* ARGSUSED */
859: static int
1.27 kristaps 860: mdoc_it_block_pre(MDOC_ARGS, int type, int comp,
861: struct roffsu *offs, struct roffsu *width)
1.1 kristaps 862: {
1.14 kristaps 863: struct htmlpair tag;
864: const struct mdoc_node *nn;
1.23 kristaps 865: struct roffsu su;
866:
867: nn = n->parent->parent;
868: assert(nn->args);
869:
1.24 kristaps 870: /* XXX: see notes in mdoc_it_pre(). */
871:
872: if (MDOC_Column == type) {
873: /* Don't width-pad on the left. */
874: SCALE_HS_INIT(width, 0);
875: /* Also disallow non-compact. */
876: comp = 1;
877: }
1.23 kristaps 878: if (MDOC_Diag == type)
1.24 kristaps 879: /* Mandate non-compact with empty prior. */
1.23 kristaps 880: if (n->prev && NULL == n->prev->body->child)
881: comp = 1;
882:
1.24 kristaps 883: bufcat_style(h, "clear", "both");
1.23 kristaps 884: if (offs->scale > 0)
885: bufcat_su(h, "margin-left", offs);
886: if (width->scale > 0)
887: bufcat_su(h, "padding-left", width);
1.1 kristaps 888:
1.23 kristaps 889: PAIR_STYLE_INIT(&tag, h);
890:
1.24 kristaps 891: /* Mandate compact following `Ss' and `Sh' starts. */
892:
1.23 kristaps 893: for (nn = n; nn && ! comp; nn = nn->parent) {
894: if (MDOC_BLOCK != nn->type)
895: continue;
896: if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok)
897: comp = 1;
898: if (nn->prev)
899: break;
1.1 kristaps 900: }
901:
1.23 kristaps 902: if ( ! comp) {
903: SCALE_VS_INIT(&su, 1);
904: bufcat_su(h, "padding-top", &su);
1.1 kristaps 905: }
906:
1.23 kristaps 907: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 908: print_otag(h, TAG_DIV, 1, &tag);
909: return(1);
910: }
911:
912:
1.25 kristaps 913: /* ARGSUSED */
1.1 kristaps 914: static int
1.23 kristaps 915: mdoc_it_body_pre(MDOC_ARGS, int type)
1.1 kristaps 916: {
1.23 kristaps 917: struct htmlpair tag;
918: struct roffsu su;
919:
920: switch (type) {
921: case (MDOC_Item):
922: /* FALLTHROUGH */
923: case (MDOC_Ohang):
924: /* FALLTHROUGH */
925: case (MDOC_Column):
926: break;
927: default:
1.24 kristaps 928: /*
929: * XXX: this tricks CSS into aligning the bodies with
930: * the right-padding in the head.
931: */
1.23 kristaps 932: SCALE_HS_INIT(&su, 2);
933: bufcat_su(h, "margin-left", &su);
934: PAIR_STYLE_INIT(&tag, h);
935: print_otag(h, TAG_DIV, 1, &tag);
936: break;
937: }
1.1 kristaps 938:
939: return(1);
940: }
941:
942:
1.25 kristaps 943: /* ARGSUSED */
1.1 kristaps 944: static int
1.23 kristaps 945: mdoc_it_head_pre(MDOC_ARGS, int type, struct roffsu *width)
1.1 kristaps 946: {
947: struct htmlpair tag;
948: struct ord *ord;
949: char nbuf[BUFSIZ];
950:
1.23 kristaps 951: switch (type) {
1.1 kristaps 952: case (MDOC_Item):
1.46 kristaps 953: return(0);
1.1 kristaps 954: case (MDOC_Ohang):
1.46 kristaps 955: print_otag(h, TAG_DIV, 0, &tag);
956: return(1);
1.1 kristaps 957: case (MDOC_Column):
1.23 kristaps 958: bufcat_su(h, "min-width", width);
959: bufcat_style(h, "clear", "none");
1.1 kristaps 960: if (n->next && MDOC_HEAD == n->next->type)
1.23 kristaps 961: bufcat_style(h, "float", "left");
962: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 963: print_otag(h, TAG_DIV, 1, &tag);
964: break;
965: default:
1.23 kristaps 966: bufcat_su(h, "min-width", width);
967: SCALE_INVERT(width);
968: bufcat_su(h, "margin-left", width);
1.2 kristaps 969: if (n->next && n->next->child)
1.23 kristaps 970: bufcat_style(h, "float", "left");
1.24 kristaps 971:
972: /* XXX: buffer if we run into body. */
1.23 kristaps 973: SCALE_HS_INIT(width, 1);
974: bufcat_su(h, "margin-right", width);
975: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 976: print_otag(h, TAG_DIV, 1, &tag);
977: break;
978: }
979:
1.23 kristaps 980: switch (type) {
1.1 kristaps 981: case (MDOC_Diag):
1.23 kristaps 982: PAIR_CLASS_INIT(&tag, "diag");
1.1 kristaps 983: print_otag(h, TAG_SPAN, 1, &tag);
984: break;
985: case (MDOC_Enum):
1.39 kristaps 986: ord = h->ords.head;
1.1 kristaps 987: assert(ord);
988: nbuf[BUFSIZ - 1] = 0;
989: (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
990: print_text(h, nbuf);
991: return(0);
992: case (MDOC_Dash):
993: print_text(h, "\\(en");
994: return(0);
995: case (MDOC_Hyphen):
1.4 kristaps 996: print_text(h, "\\(hy");
1.1 kristaps 997: return(0);
998: case (MDOC_Bullet):
999: print_text(h, "\\(bu");
1000: return(0);
1001: default:
1002: break;
1003: }
1004:
1005: return(1);
1006: }
1007:
1008:
1009: static int
1.23 kristaps 1010: mdoc_it_pre(MDOC_ARGS)
1.1 kristaps 1011: {
1.23 kristaps 1012: int i, type, wp, comp;
1.1 kristaps 1013: const struct mdoc_node *bl, *nn;
1.23 kristaps 1014: struct roffsu width, offs;
1015:
1.24 kristaps 1016: /*
1017: * XXX: be very careful in changing anything, here. Lists in
1018: * mandoc have many peculiarities; furthermore, they don't
1019: * translate well into HTML and require a bit of mangling.
1020: */
1.1 kristaps 1021:
1022: bl = n->parent->parent;
1.23 kristaps 1023: if (MDOC_BLOCK != n->type)
1.1 kristaps 1024: bl = bl->parent;
1025:
1.23 kristaps 1026: type = a2list(bl);
1.1 kristaps 1027:
1.23 kristaps 1028: /* Set default width and offset. */
1.1 kristaps 1029:
1.24 kristaps 1030: SCALE_HS_INIT(&offs, 0);
1031:
1.1 kristaps 1032: switch (type) {
1033: case (MDOC_Enum):
1034: /* FALLTHROUGH */
1035: case (MDOC_Dash):
1036: /* FALLTHROUGH */
1037: case (MDOC_Hyphen):
1038: /* FALLTHROUGH */
1039: case (MDOC_Bullet):
1.23 kristaps 1040: SCALE_HS_INIT(&width, 2);
1.1 kristaps 1041: break;
1.23 kristaps 1042: default:
1043: SCALE_HS_INIT(&width, INDENT);
1044: break;
1045: }
1046:
1047: /* Get width, offset, and compact arguments. */
1048:
1049: for (wp = -1, comp = i = 0; i < (int)bl->args->argc; i++)
1050: switch (bl->args->argv[i].arg) {
1.24 kristaps 1051: case (MDOC_Column):
1052: wp = i; /* Save for later. */
1053: break;
1.23 kristaps 1054: case (MDOC_Width):
1055: a2width(bl->args->argv[i].value[0], &width);
1056: break;
1057: case (MDOC_Offset):
1058: a2offs(bl->args->argv[i].value[0], &offs);
1059: break;
1060: case (MDOC_Compact):
1061: comp = 1;
1062: break;
1063: default:
1064: break;
1065: }
1066:
1067: /* Override width in some cases. */
1068:
1069: switch (type) {
1.46 kristaps 1070: case (MDOC_Ohang):
1071: /* FALLTHROUGH */
1.33 kristaps 1072: case (MDOC_Item):
1073: /* FALLTHROUGH */
1.1 kristaps 1074: case (MDOC_Inset):
1075: /* FALLTHROUGH */
1076: case (MDOC_Diag):
1.23 kristaps 1077: SCALE_HS_INIT(&width, 0);
1.1 kristaps 1078: break;
1079: default:
1.23 kristaps 1080: if (0 == width.scale)
1081: SCALE_HS_INIT(&width, INDENT);
1.1 kristaps 1082: break;
1083: }
1084:
1.23 kristaps 1085: /* Flip to body/block processing. */
1086:
1087: if (MDOC_BODY == n->type)
1088: return(mdoc_it_body_pre(m, n, h, type));
1089: if (MDOC_BLOCK == n->type)
1.27 kristaps 1090: return(mdoc_it_block_pre(m, n, h, type, comp,
1091: &offs, &width));
1.23 kristaps 1092:
1093: /* Override column widths. */
1094:
1095: if (MDOC_Column == type) {
1096: nn = n->parent->child;
1097: for (i = 0; nn && nn != n; nn = nn->next, i++)
1098: /* Counter... */ ;
1.24 kristaps 1099: if (i < (int)bl->args->argv[wp].sz)
1.23 kristaps 1100: a2width(bl->args->argv[wp].value[i], &width);
1.1 kristaps 1101: }
1102:
1.23 kristaps 1103: return(mdoc_it_head_pre(m, n, h, type, &width));
1.1 kristaps 1104: }
1105:
1106:
1107: /* ARGSUSED */
1108: static int
1109: mdoc_bl_pre(MDOC_ARGS)
1110: {
1111: struct ord *ord;
1112:
1113: if (MDOC_BLOCK != n->type)
1114: return(1);
1115: if (MDOC_Enum != a2list(n))
1116: return(1);
1117:
1118: ord = malloc(sizeof(struct ord));
1.43 kristaps 1119: if (NULL == ord) {
1.44 kristaps 1120: perror(NULL);
1.43 kristaps 1121: exit(EXIT_FAILURE);
1122: }
1.1 kristaps 1123: ord->cookie = n;
1124: ord->pos = 1;
1.39 kristaps 1125: ord->next = h->ords.head;
1126: h->ords.head = ord;
1.1 kristaps 1127: return(1);
1128: }
1129:
1130:
1131: /* ARGSUSED */
1132: static void
1133: mdoc_bl_post(MDOC_ARGS)
1134: {
1135: struct ord *ord;
1136:
1137: if (MDOC_BLOCK != n->type)
1138: return;
1139: if (MDOC_Enum != a2list(n))
1140: return;
1141:
1.39 kristaps 1142: ord = h->ords.head;
1.1 kristaps 1143: assert(ord);
1.39 kristaps 1144: h->ords.head = ord->next;
1.1 kristaps 1145: free(ord);
1146: }
1147:
1148:
1149: /* ARGSUSED */
1150: static int
1151: mdoc_ex_pre(MDOC_ARGS)
1152: {
1153: const struct mdoc_node *nn;
1154: struct tag *t;
1155: struct htmlpair tag;
1156:
1.23 kristaps 1157: PAIR_CLASS_INIT(&tag, "utility");
1158:
1.1 kristaps 1159: print_text(h, "The");
1160: for (nn = n->child; nn; nn = nn->next) {
1161: t = print_otag(h, TAG_SPAN, 1, &tag);
1162: print_text(h, nn->string);
1163: print_tagq(h, t);
1164:
1165: h->flags |= HTML_NOSPACE;
1166:
1167: if (nn->next && NULL == nn->next->next)
1168: print_text(h, ", and");
1169: else if (nn->next)
1170: print_text(h, ",");
1171: else
1172: h->flags &= ~HTML_NOSPACE;
1173: }
1174:
1175: if (n->child->next)
1176: print_text(h, "utilities exit");
1177: else
1178: print_text(h, "utility exits");
1179:
1180: print_text(h, "0 on success, and >0 if an error occurs.");
1181: return(0);
1182: }
1183:
1184:
1185: /* ARGSUSED */
1186: static int
1187: mdoc_dq_pre(MDOC_ARGS)
1188: {
1189:
1190: if (MDOC_BODY != n->type)
1191: return(1);
1192: print_text(h, "\\(lq");
1193: h->flags |= HTML_NOSPACE;
1194: return(1);
1195: }
1196:
1197:
1198: /* ARGSUSED */
1199: static void
1200: mdoc_dq_post(MDOC_ARGS)
1201: {
1202:
1203: if (MDOC_BODY != n->type)
1204: return;
1205: h->flags |= HTML_NOSPACE;
1206: print_text(h, "\\(rq");
1207: }
1208:
1209:
1210: /* ARGSUSED */
1211: static int
1212: mdoc_pq_pre(MDOC_ARGS)
1213: {
1214:
1215: if (MDOC_BODY != n->type)
1216: return(1);
1217: print_text(h, "\\&(");
1218: h->flags |= HTML_NOSPACE;
1219: return(1);
1220: }
1221:
1222:
1223: /* ARGSUSED */
1224: static void
1225: mdoc_pq_post(MDOC_ARGS)
1226: {
1227:
1228: if (MDOC_BODY != n->type)
1229: return;
1230: print_text(h, ")");
1231: }
1232:
1233:
1234: /* ARGSUSED */
1235: static int
1236: mdoc_sq_pre(MDOC_ARGS)
1237: {
1238:
1239: if (MDOC_BODY != n->type)
1240: return(1);
1241: print_text(h, "\\(oq");
1242: h->flags |= HTML_NOSPACE;
1243: return(1);
1244: }
1245:
1246:
1247: /* ARGSUSED */
1248: static void
1249: mdoc_sq_post(MDOC_ARGS)
1250: {
1251:
1252: if (MDOC_BODY != n->type)
1253: return;
1254: h->flags |= HTML_NOSPACE;
1255: print_text(h, "\\(aq");
1256: }
1257:
1258:
1259: /* ARGSUSED */
1260: static int
1261: mdoc_em_pre(MDOC_ARGS)
1262: {
1263: struct htmlpair tag;
1264:
1.23 kristaps 1265: PAIR_CLASS_INIT(&tag, "emph");
1.1 kristaps 1266: print_otag(h, TAG_SPAN, 1, &tag);
1267: return(1);
1268: }
1269:
1270:
1271: /* ARGSUSED */
1272: static int
1273: mdoc_d1_pre(MDOC_ARGS)
1274: {
1.23 kristaps 1275: struct htmlpair tag[2];
1276: struct roffsu su;
1.1 kristaps 1277:
1278: if (MDOC_BLOCK != n->type)
1279: return(1);
1280:
1.35 kristaps 1281: /* FIXME: D1 shouldn't be literal. */
1282:
1.23 kristaps 1283: SCALE_VS_INIT(&su, INDENT - 2);
1284: bufcat_su(h, "margin-left", &su);
1285: PAIR_CLASS_INIT(&tag[0], "lit");
1286: PAIR_STYLE_INIT(&tag[1], h);
1.1 kristaps 1287: print_otag(h, TAG_DIV, 2, tag);
1288: return(1);
1289: }
1290:
1291:
1292: /* ARGSUSED */
1293: static int
1294: mdoc_sx_pre(MDOC_ARGS)
1295: {
1.18 kristaps 1296: struct htmlpair tag[2];
1.1 kristaps 1297: const struct mdoc_node *nn;
1.35 kristaps 1298: char buf[BUFSIZ];
1.1 kristaps 1299:
1.23 kristaps 1300: /* FIXME: duplicates? */
1301:
1.41 kristaps 1302: strlcpy(buf, "#", BUFSIZ);
1.1 kristaps 1303: for (nn = n->child; nn; nn = nn->next) {
1.41 kristaps 1304: html_idcat(buf, nn->string, BUFSIZ);
1.1 kristaps 1305: if (nn->next)
1.42 kristaps 1306: html_idcat(buf, " ", BUFSIZ);
1.1 kristaps 1307: }
1308:
1.23 kristaps 1309: PAIR_CLASS_INIT(&tag[0], "link-sec");
1.21 kristaps 1310: tag[1].key = ATTR_HREF;
1.35 kristaps 1311: tag[1].val = buf;
1.1 kristaps 1312:
1.18 kristaps 1313: print_otag(h, TAG_A, 2, tag);
1.1 kristaps 1314: return(1);
1315: }
1316:
1317:
1318: /* ARGSUSED */
1319: static int
1320: mdoc_aq_pre(MDOC_ARGS)
1321: {
1322:
1323: if (MDOC_BODY != n->type)
1324: return(1);
1325: print_text(h, "\\(la");
1326: h->flags |= HTML_NOSPACE;
1327: return(1);
1328: }
1329:
1330:
1331: /* ARGSUSED */
1332: static void
1333: mdoc_aq_post(MDOC_ARGS)
1334: {
1335:
1336: if (MDOC_BODY != n->type)
1337: return;
1338: h->flags |= HTML_NOSPACE;
1339: print_text(h, "\\(ra");
1340: }
1341:
1342:
1343: /* ARGSUSED */
1344: static int
1345: mdoc_bd_pre(MDOC_ARGS)
1346: {
1347: struct htmlpair tag[2];
1.23 kristaps 1348: int type, comp, i;
1.14 kristaps 1349: const struct mdoc_node *bl, *nn;
1.23 kristaps 1350: struct roffsu su;
1.1 kristaps 1351:
1352: if (MDOC_BLOCK == n->type)
1353: bl = n;
1354: else if (MDOC_HEAD == n->type)
1355: return(0);
1356: else
1357: bl = n->parent;
1358:
1.24 kristaps 1359: SCALE_VS_INIT(&su, 0);
1360:
1.23 kristaps 1361: type = comp = 0;
1.1 kristaps 1362: for (i = 0; i < (int)bl->args->argc; i++)
1363: switch (bl->args->argv[i].arg) {
1364: case (MDOC_Offset):
1.23 kristaps 1365: a2offs(bl->args->argv[i].value[0], &su);
1.1 kristaps 1366: break;
1367: case (MDOC_Compact):
1.23 kristaps 1368: comp = 1;
1.1 kristaps 1369: break;
1.30 kristaps 1370: case (MDOC_Centred):
1371: /* FALLTHROUGH */
1.1 kristaps 1372: case (MDOC_Ragged):
1373: /* FALLTHROUGH */
1374: case (MDOC_Filled):
1375: /* FALLTHROUGH */
1376: case (MDOC_Unfilled):
1377: /* FALLTHROUGH */
1378: case (MDOC_Literal):
1.23 kristaps 1379: type = bl->args->argv[i].arg;
1.1 kristaps 1380: break;
1.30 kristaps 1381: default:
1382: break;
1.1 kristaps 1383: }
1384:
1.31 kristaps 1385: /* FIXME: -centered, etc. formatting. */
1386:
1.1 kristaps 1387: if (MDOC_BLOCK == n->type) {
1.24 kristaps 1388: bufcat_su(h, "margin-left", &su);
1.23 kristaps 1389: for (nn = n; nn && ! comp; nn = nn->parent) {
1390: if (MDOC_BLOCK != nn->type)
1391: continue;
1392: if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok)
1393: comp = 1;
1394: if (nn->prev)
1395: break;
1396: }
1397: if (comp) {
1398: print_otag(h, TAG_DIV, 0, tag);
1399: return(1);
1.14 kristaps 1400: }
1.23 kristaps 1401: SCALE_VS_INIT(&su, 1);
1402: bufcat_su(h, "margin-top", &su);
1403: PAIR_STYLE_INIT(&tag[0], h);
1.1 kristaps 1404: print_otag(h, TAG_DIV, 1, tag);
1405: return(1);
1406: }
1407:
1.23 kristaps 1408: if (MDOC_Unfilled != type && MDOC_Literal != type)
1.1 kristaps 1409: return(1);
1410:
1.23 kristaps 1411: PAIR_CLASS_INIT(&tag[0], "lit");
1412: bufcat_style(h, "white-space", "pre");
1413: PAIR_STYLE_INIT(&tag[1], h);
1.1 kristaps 1414: print_otag(h, TAG_DIV, 2, tag);
1415:
1.14 kristaps 1416: for (nn = n->child; nn; nn = nn->next) {
1.23 kristaps 1417: h->flags |= HTML_NOSPACE;
1.14 kristaps 1418: print_mdoc_node(m, nn, h);
1419: if (NULL == nn->next)
1420: continue;
1421: if (nn->prev && nn->prev->line < nn->line)
1.1 kristaps 1422: print_text(h, "\n");
1.23 kristaps 1423: else if (NULL == nn->prev)
1424: print_text(h, "\n");
1.1 kristaps 1425: }
1426:
1427: return(0);
1428: }
1429:
1430:
1431: /* ARGSUSED */
1432: static int
1433: mdoc_pa_pre(MDOC_ARGS)
1434: {
1435: struct htmlpair tag;
1436:
1.23 kristaps 1437: PAIR_CLASS_INIT(&tag, "file");
1.1 kristaps 1438: print_otag(h, TAG_SPAN, 1, &tag);
1439: return(1);
1440: }
1441:
1442:
1443: /* ARGSUSED */
1444: static int
1445: mdoc_ad_pre(MDOC_ARGS)
1446: {
1447: struct htmlpair tag;
1448:
1.23 kristaps 1449: PAIR_CLASS_INIT(&tag, "addr");
1.1 kristaps 1450: print_otag(h, TAG_SPAN, 1, &tag);
1451: return(1);
1452: }
1453:
1454:
1455: /* ARGSUSED */
1456: static int
1457: mdoc_an_pre(MDOC_ARGS)
1458: {
1459: struct htmlpair tag;
1460:
1.19 kristaps 1461: /* TODO: -split and -nosplit (see termp_an_pre()). */
1462:
1.23 kristaps 1463: PAIR_CLASS_INIT(&tag, "author");
1.1 kristaps 1464: print_otag(h, TAG_SPAN, 1, &tag);
1465: return(1);
1466: }
1467:
1468:
1469: /* ARGSUSED */
1470: static int
1471: mdoc_cd_pre(MDOC_ARGS)
1472: {
1473: struct htmlpair tag;
1474:
1.28 kristaps 1475: print_otag(h, TAG_DIV, 0, NULL);
1.23 kristaps 1476: PAIR_CLASS_INIT(&tag, "config");
1.1 kristaps 1477: print_otag(h, TAG_SPAN, 1, &tag);
1478: return(1);
1479: }
1480:
1481:
1482: /* ARGSUSED */
1483: static int
1484: mdoc_dv_pre(MDOC_ARGS)
1485: {
1486: struct htmlpair tag;
1487:
1.23 kristaps 1488: PAIR_CLASS_INIT(&tag, "define");
1.1 kristaps 1489: print_otag(h, TAG_SPAN, 1, &tag);
1490: return(1);
1491: }
1492:
1493:
1494: /* ARGSUSED */
1495: static int
1496: mdoc_ev_pre(MDOC_ARGS)
1497: {
1498: struct htmlpair tag;
1499:
1.23 kristaps 1500: PAIR_CLASS_INIT(&tag, "env");
1.1 kristaps 1501: print_otag(h, TAG_SPAN, 1, &tag);
1502: return(1);
1503: }
1504:
1505:
1506: /* ARGSUSED */
1507: static int
1508: mdoc_er_pre(MDOC_ARGS)
1509: {
1510: struct htmlpair tag;
1511:
1.23 kristaps 1512: PAIR_CLASS_INIT(&tag, "errno");
1.1 kristaps 1513: print_otag(h, TAG_SPAN, 1, &tag);
1514: return(1);
1515: }
1516:
1517:
1518: /* ARGSUSED */
1519: static int
1520: mdoc_fa_pre(MDOC_ARGS)
1521: {
1522: const struct mdoc_node *nn;
1523: struct htmlpair tag;
1524: struct tag *t;
1525:
1.23 kristaps 1526: PAIR_CLASS_INIT(&tag, "farg");
1.1 kristaps 1527: if (n->parent->tok != MDOC_Fo) {
1528: print_otag(h, TAG_SPAN, 1, &tag);
1529: return(1);
1530: }
1531:
1532: for (nn = n->child; nn; nn = nn->next) {
1533: t = print_otag(h, TAG_SPAN, 1, &tag);
1534: print_text(h, nn->string);
1535: print_tagq(h, t);
1536: if (nn->next)
1537: print_text(h, ",");
1538: }
1539:
1540: if (n->child && n->next && n->next->tok == MDOC_Fa)
1541: print_text(h, ",");
1542:
1543: return(0);
1544: }
1545:
1546:
1547: /* ARGSUSED */
1548: static int
1549: mdoc_fd_pre(MDOC_ARGS)
1550: {
1.23 kristaps 1551: struct htmlpair tag;
1552: struct roffsu su;
1.1 kristaps 1553:
1554: if (SEC_SYNOPSIS == n->sec) {
1555: if (n->next && MDOC_Fd != n->next->tok) {
1.23 kristaps 1556: SCALE_VS_INIT(&su, 1);
1557: bufcat_su(h, "margin-bottom", &su);
1558: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 1559: print_otag(h, TAG_DIV, 1, &tag);
1560: } else
1561: print_otag(h, TAG_DIV, 0, NULL);
1562: }
1563:
1.23 kristaps 1564: PAIR_CLASS_INIT(&tag, "macro");
1.1 kristaps 1565: print_otag(h, TAG_SPAN, 1, &tag);
1566: return(1);
1567: }
1568:
1569:
1570: /* ARGSUSED */
1571: static int
1572: mdoc_vt_pre(MDOC_ARGS)
1573: {
1.23 kristaps 1574: struct htmlpair tag;
1575: struct roffsu su;
1.1 kristaps 1576:
1577: if (SEC_SYNOPSIS == n->sec) {
1578: if (n->next && MDOC_Vt != n->next->tok) {
1.23 kristaps 1579: SCALE_VS_INIT(&su, 1);
1580: bufcat_su(h, "margin-bottom", &su);
1581: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 1582: print_otag(h, TAG_DIV, 1, &tag);
1583: } else
1584: print_otag(h, TAG_DIV, 0, NULL);
1585: }
1586:
1.23 kristaps 1587: PAIR_CLASS_INIT(&tag, "type");
1.1 kristaps 1588: print_otag(h, TAG_SPAN, 1, &tag);
1589: return(1);
1590: }
1591:
1.2 kristaps 1592:
1.1 kristaps 1593: /* ARGSUSED */
1594: static int
1595: mdoc_ft_pre(MDOC_ARGS)
1596: {
1.23 kristaps 1597: struct htmlpair tag;
1598: struct roffsu su;
1.1 kristaps 1599:
1600: if (SEC_SYNOPSIS == n->sec) {
1601: if (n->prev && MDOC_Fo == n->prev->tok) {
1.23 kristaps 1602: SCALE_VS_INIT(&su, 1);
1603: bufcat_su(h, "margin-top", &su);
1604: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 1605: print_otag(h, TAG_DIV, 1, &tag);
1606: } else
1607: print_otag(h, TAG_DIV, 0, NULL);
1608: }
1609:
1.23 kristaps 1610: PAIR_CLASS_INIT(&tag, "ftype");
1.1 kristaps 1611: print_otag(h, TAG_SPAN, 1, &tag);
1612: return(1);
1613: }
1614:
1615:
1616: /* ARGSUSED */
1617: static int
1618: mdoc_fn_pre(MDOC_ARGS)
1619: {
1620: struct tag *t;
1.15 kristaps 1621: struct htmlpair tag[2];
1.1 kristaps 1622: const struct mdoc_node *nn;
1.7 kristaps 1623: char nbuf[BUFSIZ];
1624: const char *sp, *ep;
1.15 kristaps 1625: int sz, i;
1.23 kristaps 1626: struct roffsu su;
1.1 kristaps 1627:
1628: if (SEC_SYNOPSIS == n->sec) {
1.23 kristaps 1629: SCALE_HS_INIT(&su, INDENT);
1630: bufcat_su(h, "margin-left", &su);
1631: su.scale = -su.scale;
1632: bufcat_su(h, "text-indent", &su);
1633: if (n->next) {
1634: SCALE_VS_INIT(&su, 1);
1635: bufcat_su(h, "margin-bottom", &su);
1636: }
1637: PAIR_STYLE_INIT(&tag[0], h);
1.15 kristaps 1638: print_otag(h, TAG_DIV, 1, tag);
1.1 kristaps 1639: }
1640:
1.7 kristaps 1641: /* Split apart into type and name. */
1642: assert(n->child->string);
1643: sp = n->child->string;
1.19 kristaps 1644:
1.26 kristaps 1645: ep = strchr(sp, ' ');
1646: if (NULL != ep) {
1.23 kristaps 1647: PAIR_CLASS_INIT(&tag[0], "ftype");
1.19 kristaps 1648: t = print_otag(h, TAG_SPAN, 1, tag);
1649:
1650: while (ep) {
1651: sz = MIN((int)(ep - sp), BUFSIZ - 1);
1652: (void)memcpy(nbuf, sp, (size_t)sz);
1653: nbuf[sz] = '\0';
1654: print_text(h, nbuf);
1655: sp = ++ep;
1656: ep = strchr(sp, ' ');
1657: }
1658: print_tagq(h, t);
1.7 kristaps 1659: }
1.1 kristaps 1660:
1.23 kristaps 1661: PAIR_CLASS_INIT(&tag[0], "fname");
1.15 kristaps 1662: t = print_otag(h, TAG_SPAN, 1, tag);
1.7 kristaps 1663:
1664: if (sp) {
1665: (void)strlcpy(nbuf, sp, BUFSIZ);
1666: print_text(h, nbuf);
1667: }
1668:
1.1 kristaps 1669: print_tagq(h, t);
1670:
1671: h->flags |= HTML_NOSPACE;
1672: print_text(h, "(");
1673:
1.23 kristaps 1674: bufinit(h);
1675: PAIR_CLASS_INIT(&tag[0], "farg");
1676: bufcat_style(h, "white-space", "nowrap");
1677: PAIR_STYLE_INIT(&tag[1], h);
1678:
1.1 kristaps 1679: for (nn = n->child->next; nn; nn = nn->next) {
1.23 kristaps 1680: i = 1;
1681: if (SEC_SYNOPSIS == n->sec)
1682: i = 2;
1.15 kristaps 1683: t = print_otag(h, TAG_SPAN, i, tag);
1.1 kristaps 1684: print_text(h, nn->string);
1685: print_tagq(h, t);
1686: if (nn->next)
1687: print_text(h, ",");
1688: }
1689:
1690: print_text(h, ")");
1691: if (SEC_SYNOPSIS == n->sec)
1692: print_text(h, ";");
1693:
1694: return(0);
1695: }
1696:
1697:
1698: /* ARGSUSED */
1699: static int
1700: mdoc_sp_pre(MDOC_ARGS)
1701: {
1.23 kristaps 1702: int len;
1703: struct htmlpair tag;
1704: struct roffsu su;
1.1 kristaps 1705:
1706: switch (n->tok) {
1707: case (MDOC_sp):
1.23 kristaps 1708: /* FIXME: can this have a scaling indicator? */
1.1 kristaps 1709: len = n->child ? atoi(n->child->string) : 1;
1710: break;
1711: case (MDOC_br):
1712: len = 0;
1713: break;
1714: default:
1715: len = 1;
1716: break;
1717: }
1718:
1.23 kristaps 1719: SCALE_VS_INIT(&su, len);
1720: bufcat_su(h, "height", &su);
1721: PAIR_STYLE_INIT(&tag, h);
1.1 kristaps 1722: print_otag(h, TAG_DIV, 1, &tag);
1.42 kristaps 1723: /* So the div isn't empty: */
1724: print_text(h, "\\~");
1725:
1726: return(0);
1.1 kristaps 1727:
1728: }
1.2 kristaps 1729:
1730:
1731: /* ARGSUSED */
1732: static int
1733: mdoc_brq_pre(MDOC_ARGS)
1734: {
1735:
1736: if (MDOC_BODY != n->type)
1737: return(1);
1738: print_text(h, "\\(lC");
1739: h->flags |= HTML_NOSPACE;
1740: return(1);
1741: }
1742:
1743:
1744: /* ARGSUSED */
1745: static void
1746: mdoc_brq_post(MDOC_ARGS)
1747: {
1748:
1749: if (MDOC_BODY != n->type)
1750: return;
1751: h->flags |= HTML_NOSPACE;
1752: print_text(h, "\\(rC");
1753: }
1754:
1755:
1756: /* ARGSUSED */
1757: static int
1758: mdoc_lk_pre(MDOC_ARGS)
1759: {
1760: const struct mdoc_node *nn;
1761: struct htmlpair tag[2];
1762:
1763: nn = n->child;
1764:
1.23 kristaps 1765: PAIR_CLASS_INIT(&tag[0], "link-ext");
1.2 kristaps 1766: tag[1].key = ATTR_HREF;
1767: tag[1].val = nn->string;
1768: print_otag(h, TAG_A, 2, tag);
1769:
1.38 kristaps 1770: if (NULL == nn->next)
1771: return(1);
1772:
1.2 kristaps 1773: for (nn = nn->next; nn; nn = nn->next)
1774: print_text(h, nn->string);
1775:
1776: return(0);
1777: }
1778:
1779:
1780: /* ARGSUSED */
1781: static int
1782: mdoc_mt_pre(MDOC_ARGS)
1783: {
1784: struct htmlpair tag[2];
1785: struct tag *t;
1786: const struct mdoc_node *nn;
1787:
1.23 kristaps 1788: PAIR_CLASS_INIT(&tag[0], "link-mail");
1.2 kristaps 1789:
1790: for (nn = n->child; nn; nn = nn->next) {
1.16 kristaps 1791: bufinit(h);
1792: bufcat(h, "mailto:");
1793: bufcat(h, nn->string);
1.23 kristaps 1794: PAIR_STYLE_INIT(&tag[1], h);
1.2 kristaps 1795: t = print_otag(h, TAG_A, 2, tag);
1796: print_text(h, nn->string);
1797: print_tagq(h, t);
1798: }
1799:
1800: return(0);
1801: }
1.4 kristaps 1802:
1803:
1804: /* ARGSUSED */
1805: static int
1806: mdoc_fo_pre(MDOC_ARGS)
1807: {
1808: struct htmlpair tag;
1809:
1810: if (MDOC_BODY == n->type) {
1811: h->flags |= HTML_NOSPACE;
1812: print_text(h, "(");
1813: h->flags |= HTML_NOSPACE;
1814: return(1);
1815: } else if (MDOC_BLOCK == n->type)
1816: return(1);
1817:
1.23 kristaps 1818: PAIR_CLASS_INIT(&tag, "fname");
1.4 kristaps 1819: print_otag(h, TAG_SPAN, 1, &tag);
1820: return(1);
1821: }
1822:
1823:
1824: /* ARGSUSED */
1825: static void
1826: mdoc_fo_post(MDOC_ARGS)
1827: {
1828: if (MDOC_BODY != n->type)
1829: return;
1830: h->flags |= HTML_NOSPACE;
1831: print_text(h, ")");
1832: h->flags |= HTML_NOSPACE;
1833: print_text(h, ";");
1834: }
1835:
1836:
1837: /* ARGSUSED */
1838: static int
1839: mdoc_in_pre(MDOC_ARGS)
1840: {
1841: const struct mdoc_node *nn;
1.23 kristaps 1842: struct tag *t;
1.17 kristaps 1843: struct htmlpair tag[2];
1844: int i;
1.23 kristaps 1845: struct roffsu su;
1.4 kristaps 1846:
1847: if (SEC_SYNOPSIS == n->sec) {
1848: if (n->next && MDOC_In != n->next->tok) {
1.23 kristaps 1849: SCALE_VS_INIT(&su, 1);
1850: bufcat_su(h, "margin-bottom", &su);
1851: PAIR_STYLE_INIT(&tag[0], h);
1.17 kristaps 1852: print_otag(h, TAG_DIV, 1, tag);
1.4 kristaps 1853: } else
1854: print_otag(h, TAG_DIV, 0, NULL);
1855: }
1856:
1.34 kristaps 1857: /* FIXME: there's a buffer bug in here somewhere. */
1858:
1.23 kristaps 1859: PAIR_CLASS_INIT(&tag[0], "includes");
1.17 kristaps 1860: print_otag(h, TAG_SPAN, 1, tag);
1.4 kristaps 1861:
1862: if (SEC_SYNOPSIS == n->sec)
1863: print_text(h, "#include");
1864:
1865: print_text(h, "<");
1866: h->flags |= HTML_NOSPACE;
1867:
1868: /* XXX -- see warning in termp_in_post(). */
1869:
1.17 kristaps 1870: for (nn = n->child; nn; nn = nn->next) {
1.23 kristaps 1871: PAIR_CLASS_INIT(&tag[0], "link-includes");
1872: i = 1;
1.41 kristaps 1873: bufinit(h);
1.17 kristaps 1874: if (h->base_includes) {
1875: buffmt_includes(h, nn->string);
1876: tag[i].key = ATTR_HREF;
1877: tag[i++].val = h->buf;
1878: }
1879: t = print_otag(h, TAG_A, i, tag);
1.4 kristaps 1880: print_mdoc_node(m, nn, h);
1.17 kristaps 1881: print_tagq(h, t);
1882: }
1.4 kristaps 1883:
1884: h->flags |= HTML_NOSPACE;
1885: print_text(h, ">");
1886:
1887: return(0);
1888: }
1889:
1890:
1891: /* ARGSUSED */
1892: static int
1893: mdoc_ic_pre(MDOC_ARGS)
1894: {
1895: struct htmlpair tag;
1896:
1.23 kristaps 1897: PAIR_CLASS_INIT(&tag, "cmd");
1.4 kristaps 1898: print_otag(h, TAG_SPAN, 1, &tag);
1899: return(1);
1900: }
1901:
1902:
1903: /* ARGSUSED */
1904: static int
1905: mdoc_rv_pre(MDOC_ARGS)
1906: {
1907: const struct mdoc_node *nn;
1908: struct htmlpair tag;
1909: struct tag *t;
1910:
1911: print_otag(h, TAG_DIV, 0, NULL);
1912: print_text(h, "The");
1913:
1914: for (nn = n->child; nn; nn = nn->next) {
1.23 kristaps 1915: PAIR_CLASS_INIT(&tag, "fname");
1.4 kristaps 1916: t = print_otag(h, TAG_SPAN, 1, &tag);
1917: print_text(h, nn->string);
1918: print_tagq(h, t);
1919:
1920: h->flags |= HTML_NOSPACE;
1921: if (nn->next && NULL == nn->next->next)
1922: print_text(h, "(), and");
1923: else if (nn->next)
1924: print_text(h, "(),");
1925: else
1926: print_text(h, "()");
1927: }
1928:
1929: if (n->child->next)
1930: print_text(h, "functions return");
1931: else
1932: print_text(h, "function returns");
1933:
1934: print_text(h, "the value 0 if successful; otherwise the value "
1935: "-1 is returned and the global variable");
1936:
1.23 kristaps 1937: PAIR_CLASS_INIT(&tag, "var");
1.4 kristaps 1938: t = print_otag(h, TAG_SPAN, 1, &tag);
1939: print_text(h, "errno");
1940: print_tagq(h, t);
1941: print_text(h, "is set to indicate the error.");
1942: return(0);
1943: }
1944:
1945:
1946: /* ARGSUSED */
1947: static int
1948: mdoc_va_pre(MDOC_ARGS)
1949: {
1950: struct htmlpair tag;
1951:
1.23 kristaps 1952: PAIR_CLASS_INIT(&tag, "var");
1.4 kristaps 1953: print_otag(h, TAG_SPAN, 1, &tag);
1954: return(1);
1955: }
1956:
1957:
1958: /* ARGSUSED */
1959: static int
1960: mdoc_bq_pre(MDOC_ARGS)
1961: {
1962:
1963: if (MDOC_BODY != n->type)
1964: return(1);
1965: print_text(h, "\\(lB");
1966: h->flags |= HTML_NOSPACE;
1967: return(1);
1968: }
1969:
1970:
1971: /* ARGSUSED */
1972: static void
1973: mdoc_bq_post(MDOC_ARGS)
1974: {
1975:
1976: if (MDOC_BODY != n->type)
1977: return;
1978: h->flags |= HTML_NOSPACE;
1979: print_text(h, "\\(rB");
1980: }
1.5 kristaps 1981:
1982:
1983: /* ARGSUSED */
1984: static int
1985: mdoc_ap_pre(MDOC_ARGS)
1986: {
1987:
1988: h->flags |= HTML_NOSPACE;
1989: print_text(h, "\\(aq");
1990: h->flags |= HTML_NOSPACE;
1991: return(1);
1992: }
1993:
1994:
1995: /* ARGSUSED */
1996: static int
1997: mdoc_bf_pre(MDOC_ARGS)
1998: {
1.23 kristaps 1999: int i;
2000: struct htmlpair tag[2];
2001: struct roffsu su;
1.5 kristaps 2002:
2003: if (MDOC_HEAD == n->type)
2004: return(0);
2005: else if (MDOC_BLOCK != n->type)
2006: return(1);
2007:
1.23 kristaps 2008: PAIR_CLASS_INIT(&tag[0], "lit");
1.5 kristaps 2009:
2010: if (n->head->child) {
2011: if ( ! strcmp("Em", n->head->child->string))
1.23 kristaps 2012: PAIR_CLASS_INIT(&tag[0], "emph");
1.5 kristaps 2013: else if ( ! strcmp("Sy", n->head->child->string))
1.23 kristaps 2014: PAIR_CLASS_INIT(&tag[0], "symb");
1.5 kristaps 2015: else if ( ! strcmp("Li", n->head->child->string))
1.23 kristaps 2016: PAIR_CLASS_INIT(&tag[0], "lit");
1.5 kristaps 2017: } else {
2018: assert(n->args);
2019: for (i = 0; i < (int)n->args->argc; i++)
2020: switch (n->args->argv[i].arg) {
2021: case (MDOC_Symbolic):
1.23 kristaps 2022: PAIR_CLASS_INIT(&tag[0], "symb");
1.5 kristaps 2023: break;
2024: case (MDOC_Literal):
1.23 kristaps 2025: PAIR_CLASS_INIT(&tag[0], "lit");
1.5 kristaps 2026: break;
2027: case (MDOC_Emphasis):
1.23 kristaps 2028: PAIR_CLASS_INIT(&tag[0], "emph");
1.5 kristaps 2029: break;
2030: default:
2031: break;
2032: }
2033: }
2034:
2035: /* FIXME: div's have spaces stripped--we want them. */
2036:
1.23 kristaps 2037: bufcat_style(h, "display", "inline");
2038: SCALE_HS_INIT(&su, 1);
2039: bufcat_su(h, "margin-right", &su);
2040: PAIR_STYLE_INIT(&tag[1], h);
1.5 kristaps 2041: print_otag(h, TAG_DIV, 2, tag);
2042: return(1);
2043: }
2044:
2045:
2046: /* ARGSUSED */
2047: static int
2048: mdoc_ms_pre(MDOC_ARGS)
2049: {
2050: struct htmlpair tag;
2051:
1.23 kristaps 2052: PAIR_CLASS_INIT(&tag, "symb");
1.5 kristaps 2053: print_otag(h, TAG_SPAN, 1, &tag);
2054: return(1);
2055: }
2056:
2057:
2058: /* ARGSUSED */
2059: static int
2060: mdoc_pf_pre(MDOC_ARGS)
2061: {
2062:
2063: h->flags |= HTML_IGNDELIM;
2064: return(1);
2065: }
2066:
2067:
2068: /* ARGSUSED */
2069: static void
2070: mdoc_pf_post(MDOC_ARGS)
2071: {
2072:
2073: h->flags &= ~HTML_IGNDELIM;
2074: h->flags |= HTML_NOSPACE;
2075: }
2076:
2077:
2078: /* ARGSUSED */
2079: static int
2080: mdoc_rs_pre(MDOC_ARGS)
2081: {
1.23 kristaps 2082: struct htmlpair tag;
2083: struct roffsu su;
1.5 kristaps 2084:
2085: if (MDOC_BLOCK != n->type)
2086: return(1);
2087:
1.8 kristaps 2088: if (n->prev && SEC_SEE_ALSO == n->sec) {
1.23 kristaps 2089: SCALE_VS_INIT(&su, 1);
2090: bufcat_su(h, "margin-top", &su);
2091: PAIR_STYLE_INIT(&tag, h);
1.8 kristaps 2092: print_otag(h, TAG_DIV, 1, &tag);
1.5 kristaps 2093: }
2094:
1.23 kristaps 2095: PAIR_CLASS_INIT(&tag, "ref");
1.8 kristaps 2096: print_otag(h, TAG_SPAN, 1, &tag);
1.5 kristaps 2097: return(1);
2098: }
1.6 kristaps 2099:
2100:
2101:
2102: /* ARGSUSED */
2103: static int
2104: mdoc_li_pre(MDOC_ARGS)
2105: {
2106: struct htmlpair tag;
2107:
1.23 kristaps 2108: PAIR_CLASS_INIT(&tag, "lit");
1.6 kristaps 2109: print_otag(h, TAG_SPAN, 1, &tag);
2110: return(1);
2111: }
2112:
2113:
2114: /* ARGSUSED */
2115: static int
2116: mdoc_sy_pre(MDOC_ARGS)
2117: {
2118: struct htmlpair tag;
2119:
1.23 kristaps 2120: PAIR_CLASS_INIT(&tag, "symb");
1.6 kristaps 2121: print_otag(h, TAG_SPAN, 1, &tag);
2122: return(1);
2123: }
2124:
2125:
2126: /* ARGSUSED */
2127: static int
2128: mdoc_bt_pre(MDOC_ARGS)
2129: {
2130:
2131: print_text(h, "is currently in beta test.");
2132: return(0);
2133: }
2134:
2135:
2136: /* ARGSUSED */
2137: static int
2138: mdoc_ud_pre(MDOC_ARGS)
2139: {
2140:
2141: print_text(h, "currently under development.");
2142: return(0);
2143: }
2144:
2145:
2146: /* ARGSUSED */
2147: static int
2148: mdoc_lb_pre(MDOC_ARGS)
2149: {
2150: struct htmlpair tag;
2151:
2152: if (SEC_SYNOPSIS == n->sec)
2153: print_otag(h, TAG_DIV, 0, NULL);
1.23 kristaps 2154: PAIR_CLASS_INIT(&tag, "lib");
1.6 kristaps 2155: print_otag(h, TAG_SPAN, 1, &tag);
2156: return(1);
2157: }
1.10 kristaps 2158:
2159:
2160: /* ARGSUSED */
2161: static int
2162: mdoc__x_pre(MDOC_ARGS)
2163: {
1.38 kristaps 2164: struct htmlpair tag[2];
1.37 kristaps 2165:
1.10 kristaps 2166: switch (n->tok) {
2167: case(MDOC__A):
1.38 kristaps 2168: PAIR_CLASS_INIT(&tag[0], "ref-auth");
1.10 kristaps 2169: break;
2170: case(MDOC__B):
1.38 kristaps 2171: PAIR_CLASS_INIT(&tag[0], "ref-book");
1.10 kristaps 2172: break;
2173: case(MDOC__C):
1.38 kristaps 2174: PAIR_CLASS_INIT(&tag[0], "ref-city");
1.10 kristaps 2175: break;
2176: case(MDOC__D):
1.38 kristaps 2177: PAIR_CLASS_INIT(&tag[0], "ref-date");
1.10 kristaps 2178: break;
2179: case(MDOC__I):
1.38 kristaps 2180: PAIR_CLASS_INIT(&tag[0], "ref-issue");
1.10 kristaps 2181: break;
2182: case(MDOC__J):
1.38 kristaps 2183: PAIR_CLASS_INIT(&tag[0], "ref-jrnl");
1.10 kristaps 2184: break;
2185: case(MDOC__N):
1.38 kristaps 2186: PAIR_CLASS_INIT(&tag[0], "ref-num");
1.10 kristaps 2187: break;
2188: case(MDOC__O):
1.38 kristaps 2189: PAIR_CLASS_INIT(&tag[0], "ref-opt");
1.10 kristaps 2190: break;
2191: case(MDOC__P):
1.38 kristaps 2192: PAIR_CLASS_INIT(&tag[0], "ref-page");
1.10 kristaps 2193: break;
2194: case(MDOC__Q):
1.38 kristaps 2195: PAIR_CLASS_INIT(&tag[0], "ref-corp");
1.10 kristaps 2196: break;
2197: case(MDOC__R):
1.38 kristaps 2198: PAIR_CLASS_INIT(&tag[0], "ref-rep");
1.10 kristaps 2199: break;
2200: case(MDOC__T):
1.38 kristaps 2201: PAIR_CLASS_INIT(&tag[0], "ref-title");
1.10 kristaps 2202: print_text(h, "\\(lq");
2203: h->flags |= HTML_NOSPACE;
2204: break;
1.38 kristaps 2205: case(MDOC__U):
2206: PAIR_CLASS_INIT(&tag[0], "link-ref");
2207: break;
1.10 kristaps 2208: case(MDOC__V):
1.38 kristaps 2209: PAIR_CLASS_INIT(&tag[0], "ref-vol");
1.10 kristaps 2210: break;
2211: default:
2212: abort();
2213: /* NOTREACHED */
2214: }
2215:
1.38 kristaps 2216: if (MDOC__U != n->tok) {
2217: print_otag(h, TAG_SPAN, 1, tag);
2218: return(1);
2219: }
2220:
2221: PAIR_HREF_INIT(&tag[1], n->child->string);
2222: print_otag(h, TAG_A, 2, tag);
1.10 kristaps 2223: return(1);
2224: }
2225:
2226:
2227: /* ARGSUSED */
2228: static void
2229: mdoc__x_post(MDOC_ARGS)
2230: {
2231:
2232: h->flags |= HTML_NOSPACE;
2233: switch (n->tok) {
2234: case (MDOC__T):
2235: print_text(h, "\\(rq");
2236: h->flags |= HTML_NOSPACE;
2237: break;
2238: default:
2239: break;
2240: }
2241: print_text(h, n->next ? "," : ".");
2242: }
CVSweb