Annotation of mandoc/mdoc_html.c, Revision 1.5
1.5 ! kristaps 1: /* $Id: mdoc_html.c,v 1.4 2009/09/24 09:20:02 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>
18: #include <sys/queue.h>
19:
20: #include <assert.h>
21: #include <ctype.h>
22: #include <err.h>
23: #include <stdio.h>
24: #include <stdlib.h>
25: #include <string.h>
26: #include <unistd.h>
27:
28: #include "html.h"
29: #include "mdoc.h"
30:
31: #define INDENT 5
32: #define HALFINDENT 3
33:
34: #define MDOC_ARGS const struct mdoc_meta *m, \
35: const struct mdoc_node *n, \
36: struct html *h
37: #define MAN_ARGS const struct man_meta *m, \
38: const struct man_node *n, \
39: struct html *h
40:
41: struct htmlmdoc {
42: int (*pre)(MDOC_ARGS);
43: void (*post)(MDOC_ARGS);
44: };
45:
46: static void print_mdoc(MDOC_ARGS);
47: static void print_mdoc_head(MDOC_ARGS);
48: static void print_mdoc_node(MDOC_ARGS);
49: static void print_mdoc_nodelist(MDOC_ARGS);
50:
51: static int a2width(const char *);
52: static int a2offs(const char *);
53: static int a2list(const struct mdoc_node *);
54:
55: static void mdoc_root_post(MDOC_ARGS);
56: static int mdoc_root_pre(MDOC_ARGS);
57: static int mdoc_tbl_pre(MDOC_ARGS, int);
58: static int mdoc_tbl_block_pre(MDOC_ARGS, int, int, int, int);
59: static int mdoc_tbl_body_pre(MDOC_ARGS, int, int);
60: static int mdoc_tbl_head_pre(MDOC_ARGS, int, int);
61:
62: static int mdoc_ad_pre(MDOC_ARGS);
63: static int mdoc_an_pre(MDOC_ARGS);
1.5 ! kristaps 64: static int mdoc_ap_pre(MDOC_ARGS);
1.1 kristaps 65: static void mdoc_aq_post(MDOC_ARGS);
66: static int mdoc_aq_pre(MDOC_ARGS);
67: static int mdoc_ar_pre(MDOC_ARGS);
68: static int mdoc_bd_pre(MDOC_ARGS);
1.5 ! kristaps 69: static int mdoc_bf_pre(MDOC_ARGS);
1.1 kristaps 70: static void mdoc_bl_post(MDOC_ARGS);
71: static int mdoc_bl_pre(MDOC_ARGS);
1.4 kristaps 72: static void mdoc_bq_post(MDOC_ARGS);
73: static int mdoc_bq_pre(MDOC_ARGS);
1.2 kristaps 74: static void mdoc_brq_post(MDOC_ARGS);
75: static int mdoc_brq_pre(MDOC_ARGS);
1.4 kristaps 76: static int mdoc_bx_pre(MDOC_ARGS);
1.1 kristaps 77: static int mdoc_cd_pre(MDOC_ARGS);
78: static int mdoc_d1_pre(MDOC_ARGS);
79: static void mdoc_dq_post(MDOC_ARGS);
80: static int mdoc_dq_pre(MDOC_ARGS);
81: static int mdoc_dv_pre(MDOC_ARGS);
82: static int mdoc_fa_pre(MDOC_ARGS);
83: static int mdoc_fd_pre(MDOC_ARGS);
84: static int mdoc_fl_pre(MDOC_ARGS);
85: static int mdoc_fn_pre(MDOC_ARGS);
86: static int mdoc_ft_pre(MDOC_ARGS);
87: static int mdoc_em_pre(MDOC_ARGS);
88: static int mdoc_er_pre(MDOC_ARGS);
89: static int mdoc_ev_pre(MDOC_ARGS);
90: static int mdoc_ex_pre(MDOC_ARGS);
1.4 kristaps 91: static void mdoc_fo_post(MDOC_ARGS);
92: static int mdoc_fo_pre(MDOC_ARGS);
93: static int mdoc_ic_pre(MDOC_ARGS);
94: static int mdoc_in_pre(MDOC_ARGS);
1.1 kristaps 95: static int mdoc_it_pre(MDOC_ARGS);
1.2 kristaps 96: static int mdoc_lk_pre(MDOC_ARGS);
97: static int mdoc_mt_pre(MDOC_ARGS);
1.5 ! kristaps 98: static int mdoc_ms_pre(MDOC_ARGS);
1.1 kristaps 99: static int mdoc_nd_pre(MDOC_ARGS);
100: static int mdoc_nm_pre(MDOC_ARGS);
101: static int mdoc_ns_pre(MDOC_ARGS);
102: static void mdoc_op_post(MDOC_ARGS);
103: static int mdoc_op_pre(MDOC_ARGS);
104: static int mdoc_pa_pre(MDOC_ARGS);
1.5 ! kristaps 105: static void mdoc_pf_post(MDOC_ARGS);
! 106: static int mdoc_pf_pre(MDOC_ARGS);
1.1 kristaps 107: static void mdoc_pq_post(MDOC_ARGS);
108: static int mdoc_pq_pre(MDOC_ARGS);
1.5 ! kristaps 109: static int mdoc_rs_pre(MDOC_ARGS);
1.4 kristaps 110: static int mdoc_rv_pre(MDOC_ARGS);
1.1 kristaps 111: static int mdoc_sh_pre(MDOC_ARGS);
112: static int mdoc_sp_pre(MDOC_ARGS);
113: static void mdoc_sq_post(MDOC_ARGS);
114: static int mdoc_sq_pre(MDOC_ARGS);
115: static int mdoc_ss_pre(MDOC_ARGS);
116: static int mdoc_sx_pre(MDOC_ARGS);
1.4 kristaps 117: static int mdoc_va_pre(MDOC_ARGS);
1.1 kristaps 118: static int mdoc_vt_pre(MDOC_ARGS);
119: static int mdoc_xr_pre(MDOC_ARGS);
120: static int mdoc_xx_pre(MDOC_ARGS);
121:
122: #ifdef __linux__
123: extern size_t strlcpy(char *, const char *, size_t);
124: extern size_t strlcat(char *, const char *, size_t);
125: #endif
126:
127: static const struct htmlmdoc mdocs[MDOC_MAX] = {
1.5 ! kristaps 128: {mdoc_ap_pre, NULL}, /* Ap */
1.1 kristaps 129: {NULL, NULL}, /* Dd */
130: {NULL, NULL}, /* Dt */
131: {NULL, NULL}, /* Os */
132: {mdoc_sh_pre, NULL }, /* Sh */
133: {mdoc_ss_pre, NULL }, /* Ss */
134: {mdoc_sp_pre, NULL}, /* Pp */
135: {mdoc_d1_pre, NULL}, /* D1 */
136: {mdoc_d1_pre, NULL}, /* Dl */
137: {mdoc_bd_pre, NULL}, /* Bd */
138: {NULL, NULL}, /* Ed */
139: {mdoc_bl_pre, mdoc_bl_post}, /* Bl */
140: {NULL, NULL}, /* El */
141: {mdoc_it_pre, NULL}, /* It */
142: {mdoc_ad_pre, NULL}, /* Ad */
143: {mdoc_an_pre, NULL}, /* An */
144: {mdoc_ar_pre, NULL}, /* Ar */
145: {mdoc_cd_pre, NULL}, /* Cd */
146: {mdoc_fl_pre, NULL}, /* Cm */
147: {mdoc_dv_pre, NULL}, /* Dv */
148: {mdoc_er_pre, NULL}, /* Er */
149: {mdoc_ev_pre, NULL}, /* Ev */
150: {mdoc_ex_pre, NULL}, /* Ex */
151: {mdoc_fa_pre, NULL}, /* Fa */
152: {mdoc_fd_pre, NULL}, /* Fd */
153: {mdoc_fl_pre, NULL}, /* Fl */
154: {mdoc_fn_pre, NULL}, /* Fn */
155: {mdoc_ft_pre, NULL}, /* Ft */
1.4 kristaps 156: {mdoc_ic_pre, NULL}, /* Ic */
157: {mdoc_in_pre, NULL}, /* In */
1.1 kristaps 158: {NULL, NULL}, /* Li */
159: {mdoc_nd_pre, NULL}, /* Nd */
160: {mdoc_nm_pre, NULL}, /* Nm */
161: {mdoc_op_pre, mdoc_op_post}, /* Op */
162: {NULL, NULL}, /* Ot */
163: {mdoc_pa_pre, NULL}, /* Pa */
1.4 kristaps 164: {mdoc_rv_pre, NULL}, /* Rv */
1.1 kristaps 165: {NULL, NULL}, /* St */
1.4 kristaps 166: {mdoc_va_pre, NULL}, /* Va */
1.1 kristaps 167: {mdoc_vt_pre, NULL}, /* Vt */
168: {mdoc_xr_pre, NULL}, /* Xr */
169: {NULL, NULL}, /* %A */
170: {NULL, NULL}, /* %B */
171: {NULL, NULL}, /* %D */
172: {NULL, NULL}, /* %I */
173: {NULL, NULL}, /* %J */
174: {NULL, NULL}, /* %N */
175: {NULL, NULL}, /* %O */
176: {NULL, NULL}, /* %P */
177: {NULL, NULL}, /* %R */
178: {NULL, NULL}, /* %T */
179: {NULL, NULL}, /* %V */
180: {NULL, NULL}, /* Ac */
181: {mdoc_aq_pre, mdoc_aq_post}, /* Ao */
182: {mdoc_aq_pre, mdoc_aq_post}, /* Aq */
183: {NULL, NULL}, /* At */
184: {NULL, NULL}, /* Bc */
1.5 ! kristaps 185: {mdoc_bf_pre, NULL}, /* Bf */
1.4 kristaps 186: {mdoc_bq_pre, mdoc_bq_post}, /* Bo */
187: {mdoc_bq_pre, mdoc_bq_post}, /* Bq */
1.1 kristaps 188: {mdoc_xx_pre, NULL}, /* Bsx */
1.4 kristaps 189: {mdoc_bx_pre, NULL}, /* Bx */
1.1 kristaps 190: {NULL, NULL}, /* Db */
191: {NULL, NULL}, /* Dc */
1.4 kristaps 192: {mdoc_dq_pre, mdoc_dq_post}, /* Do */
1.1 kristaps 193: {mdoc_dq_pre, mdoc_dq_post}, /* Dq */
194: {NULL, NULL}, /* Ec */
195: {NULL, NULL}, /* Ef */
196: {mdoc_em_pre, NULL}, /* Em */
197: {NULL, NULL}, /* Eo */
198: {mdoc_xx_pre, NULL}, /* Fx */
1.5 ! kristaps 199: {mdoc_ms_pre, NULL}, /* Ms */ /* FIXME: convert to symbol? */
1.1 kristaps 200: {NULL, NULL}, /* No */
201: {mdoc_ns_pre, NULL}, /* Ns */
202: {mdoc_xx_pre, NULL}, /* Nx */
203: {mdoc_xx_pre, NULL}, /* Ox */
204: {NULL, NULL}, /* Pc */
1.5 ! kristaps 205: {mdoc_pf_pre, mdoc_pf_post}, /* Pf */
1.1 kristaps 206: {mdoc_pq_pre, mdoc_pq_post}, /* Po */
207: {mdoc_pq_pre, mdoc_pq_post}, /* Pq */
208: {NULL, NULL}, /* Qc */
1.4 kristaps 209: {mdoc_sq_pre, mdoc_sq_post}, /* Ql */
1.5 ! kristaps 210: {mdoc_dq_pre, mdoc_dq_post}, /* Qo */
! 211: {mdoc_dq_pre, mdoc_dq_post}, /* Qq */
1.1 kristaps 212: {NULL, NULL}, /* Re */
1.5 ! kristaps 213: {mdoc_rs_pre, NULL}, /* Rs */
1.1 kristaps 214: {NULL, NULL}, /* Sc */
215: {mdoc_sq_pre, mdoc_sq_post}, /* So */
216: {mdoc_sq_pre, mdoc_sq_post}, /* Sq */
217: {NULL, NULL}, /* Sm */
218: {mdoc_sx_pre, NULL}, /* Sx */
219: {NULL, NULL}, /* Sy */
220: {NULL, NULL}, /* Tn */
221: {mdoc_xx_pre, NULL}, /* Ux */
222: {NULL, NULL}, /* Xc */
223: {NULL, NULL}, /* Xo */
1.4 kristaps 224: {mdoc_fo_pre, mdoc_fo_post}, /* Fo */
1.1 kristaps 225: {NULL, NULL}, /* Fc */
1.4 kristaps 226: {mdoc_op_pre, mdoc_op_post}, /* Oo */
1.1 kristaps 227: {NULL, NULL}, /* Oc */
228: {NULL, NULL}, /* Bk */
229: {NULL, NULL}, /* Ek */
230: {NULL, NULL}, /* Bt */
231: {NULL, NULL}, /* Hf */
232: {NULL, NULL}, /* Fr */
233: {NULL, NULL}, /* Ud */
234: {NULL, NULL}, /* Lb */
235: {mdoc_sp_pre, NULL}, /* Lp */
1.2 kristaps 236: {mdoc_lk_pre, NULL}, /* Lk */
237: {mdoc_mt_pre, NULL}, /* Mt */
238: {mdoc_brq_pre, mdoc_brq_post}, /* Brq */
239: {mdoc_brq_pre, mdoc_brq_post}, /* Bro */
1.1 kristaps 240: {NULL, NULL}, /* Brc */
241: {NULL, NULL}, /* %C */
1.2 kristaps 242: {NULL, NULL}, /* Es */ /* TODO */
243: {NULL, NULL}, /* En */ /* TODO */
1.1 kristaps 244: {mdoc_xx_pre, NULL}, /* Dx */
245: {NULL, NULL}, /* %Q */
246: {mdoc_sp_pre, NULL}, /* br */
247: {mdoc_sp_pre, NULL}, /* sp */
248: };
249:
250: static char buf[BUFSIZ]; /* XXX */
251:
252: #define bufcat(x) (void)strlcat(buf, (x), BUFSIZ)
253: #define bufinit() buf[0] = 0
254: #define buffmt(...) (void)snprintf(buf, BUFSIZ - 1, __VA_ARGS__)
255:
256: void
257: html_mdoc(void *arg, const struct mdoc *m)
258: {
259: struct html *h;
260: struct tag *t;
261:
262: h = (struct html *)arg;
263:
264: print_gen_doctype(h);
265: t = print_otag(h, TAG_HTML, 0, NULL);
266: print_mdoc(mdoc_meta(m), mdoc_node(m), h);
267: print_tagq(h, t);
268:
269: printf("\n");
270: }
271:
272:
273: static int
274: a2list(const struct mdoc_node *n)
275: {
276: int i;
277:
278: assert(MDOC_BLOCK == n->type && MDOC_Bl == n->tok);
279: assert(n->args);
280:
281: for (i = 0; i < (int)n->args->argc; i++)
282: switch (n->args->argv[i].arg) {
283: case (MDOC_Enum):
284: /* FALLTHROUGH */
285: case (MDOC_Dash):
286: /* FALLTHROUGH */
287: case (MDOC_Hyphen):
288: /* FALLTHROUGH */
289: case (MDOC_Bullet):
290: /* FALLTHROUGH */
291: case (MDOC_Tag):
292: /* FALLTHROUGH */
293: case (MDOC_Hang):
294: /* FALLTHROUGH */
295: case (MDOC_Inset):
296: /* FALLTHROUGH */
297: case (MDOC_Diag):
298: /* FALLTHROUGH */
299: case (MDOC_Item):
300: /* FALLTHROUGH */
301: case (MDOC_Column):
302: /* FALLTHROUGH */
303: case (MDOC_Ohang):
304: return(n->args->argv[i].arg);
305: default:
306: break;
307: }
308:
309: abort();
310: /* NOTREACHED */
311: }
312:
313:
314: static int
315: a2width(const char *p)
316: {
317: int i, len;
318:
319: if (0 == (len = (int)strlen(p)))
320: return(0);
321: for (i = 0; i < len - 1; i++)
322: if ( ! isdigit((u_char)p[i]))
323: break;
324:
325: if (i == len - 1)
326: if ('n' == p[len - 1] || 'm' == p[len - 1])
327: return(atoi(p) + 2);
328:
329: return(len + 2);
330: }
331:
332:
333: static int
334: a2offs(const char *p)
335: {
336: int len, i;
337:
338: if (0 == strcmp(p, "left"))
339: return(0);
340: if (0 == strcmp(p, "indent"))
341: return(INDENT + 1);
342: if (0 == strcmp(p, "indent-two"))
343: return((INDENT + 1) * 2);
344:
345: if (0 == (len = (int)strlen(p)))
346: return(0);
347:
348: for (i = 0; i < len - 1; i++)
349: if ( ! isdigit((u_char)p[i]))
350: break;
351:
352: if (i == len - 1)
353: if ('n' == p[len - 1] || 'm' == p[len - 1])
354: return(atoi(p));
355:
356: return(len);
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: char b[BUFSIZ];
386:
387: print_gen_head(h);
388:
389: (void)snprintf(b, BUFSIZ - 1,
390: "%s(%d)", m->title, m->msec);
391:
392: if (m->arch) {
393: (void)strlcat(b, " (", BUFSIZ);
394: (void)strlcat(b, m->arch, BUFSIZ);
395: (void)strlcat(b, ")", BUFSIZ);
396: }
397:
398: print_otag(h, TAG_TITLE, 0, NULL);
399: print_text(h, b);
400: }
401:
402:
403: static void
404: print_mdoc_nodelist(MDOC_ARGS)
405: {
406:
407: print_mdoc_node(m, n, h);
408: if (n->next)
409: print_mdoc_nodelist(m, n->next, h);
410: }
411:
412:
413: static void
414: print_mdoc_node(MDOC_ARGS)
415: {
416: int child;
417: struct tag *t;
418:
419: child = 1;
420: t = SLIST_FIRST(&h->tags);
421:
422: bufinit();
423:
424: switch (n->type) {
425: case (MDOC_ROOT):
426: child = mdoc_root_pre(m, n, h);
427: break;
428: case (MDOC_TEXT):
429: print_text(h, n->string);
430: break;
431: default:
432: if (mdocs[n->tok].pre)
433: child = (*mdocs[n->tok].pre)(m, n, h);
434: break;
435: }
436:
437: if (child && n->child)
438: print_mdoc_nodelist(m, n->child, h);
439:
440: print_stagq(h, t);
441:
442: bufinit();
443:
444: switch (n->type) {
445: case (MDOC_ROOT):
446: mdoc_root_post(m, n, h);
447: break;
448: case (MDOC_TEXT):
449: break;
450: default:
451: if (mdocs[n->tok].post)
452: (*mdocs[n->tok].post)(m, n, h);
453: break;
454: }
455: }
456:
457:
458: /* ARGSUSED */
459: static void
460: mdoc_root_post(MDOC_ARGS)
461: {
462: struct tm tm;
463: struct htmlpair tag[2];
464: struct tag *t, *tt;
465: char b[BUFSIZ];
466:
467: (void)localtime_r(&m->date, &tm);
468:
469: if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
470: err(EXIT_FAILURE, "strftime");
471:
472: tag[0].key = ATTR_CLASS;
473: tag[0].val = "footer";
474: tag[1].key = ATTR_STYLE;
475: tag[1].val = "width: 100%;";
476: t = print_otag(h, TAG_TABLE, 2, tag);
477: tt = print_otag(h, TAG_TR, 0, NULL);
478:
479: tag[0].key = ATTR_STYLE;
480: tag[0].val = "width: 50%;";
481: print_otag(h, TAG_TD, 1, tag);
482: print_text(h, b);
483: print_stagq(h, tt);
484:
485: tag[0].key = ATTR_STYLE;
486: tag[0].val = "width: 50%; text-align: right;";
487: print_otag(h, TAG_TD, 1, tag);
488: print_text(h, m->os);
489: print_tagq(h, t);
490: }
491:
492:
493: /* ARGSUSED */
494: static int
495: mdoc_root_pre(MDOC_ARGS)
496: {
497: struct htmlpair tag[2];
498: struct tag *t, *tt;
499: char b[BUFSIZ], title[BUFSIZ];
500:
501: (void)strlcpy(b, m->vol, BUFSIZ);
502:
503: if (m->arch) {
504: (void)strlcat(b, " (", BUFSIZ);
505: (void)strlcat(b, m->arch, BUFSIZ);
506: (void)strlcat(b, ")", BUFSIZ);
507: }
508:
509: (void)snprintf(title, BUFSIZ - 1,
510: "%s(%d)", m->title, m->msec);
511:
512: tag[0].key = ATTR_CLASS;
513: tag[0].val = "header";
514: tag[1].key = ATTR_STYLE;
515: tag[1].val = "width: 100%;";
516: t = print_otag(h, TAG_TABLE, 2, tag);
517: tt = print_otag(h, TAG_TR, 0, NULL);
518:
519: tag[0].key = ATTR_STYLE;
520: tag[0].val = "width: 33%;";
521: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 522: print_text(h, title);
1.1 kristaps 523: print_stagq(h, tt);
524:
525: tag[0].key = ATTR_STYLE;
526: tag[0].val = "width: 33%; text-align: center;";
527: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 528: print_text(h, b);
1.1 kristaps 529: print_stagq(h, tt);
530:
531: tag[0].key = ATTR_STYLE;
532: tag[0].val = "width: 33%; text-align: right;";
533: print_otag(h, TAG_TD, 1, tag);
1.2 kristaps 534: print_text(h, title);
1.1 kristaps 535: print_tagq(h, t);
536:
537: return(1);
538: }
539:
540:
541: /* ARGSUSED */
542: static int
543: mdoc_sh_pre(MDOC_ARGS)
544: {
545: struct htmlpair tag[2];
546: const struct mdoc_node *nn;
547:
548: if (MDOC_HEAD == n->type) {
549: tag[0].key = ATTR_CLASS;
550: tag[0].val = "sec-head";
551: print_otag(h, TAG_DIV, 1, tag);
552: print_otag(h, TAG_SPAN, 1, tag);
553:
554: for (nn = n->child; nn; nn = nn->next) {
555: bufcat(nn->string);
556: if (nn->next)
557: bufcat(" ");
558: }
559: tag[0].key = ATTR_NAME;
560: tag[0].val = buf;
561: print_otag(h, TAG_A, 1, tag);
562: return(1);
563: } else if (MDOC_BLOCK == n->type) {
564: tag[0].key = ATTR_CLASS;
565: tag[0].val = "sec-block";
566:
567: if (n->prev && NULL == n->prev->body->child) {
568: print_otag(h, TAG_DIV, 1, tag);
569: return(1);
570: }
571:
572: bufcat("margin-top: 1em;");
573: if (NULL == n->next)
574: bufcat("margin-bottom: 1em;");
575:
576: tag[1].key = ATTR_STYLE;
577: tag[1].val = buf;
578:
579: print_otag(h, TAG_DIV, 2, tag);
580: return(1);
581: }
582:
583: buffmt("margin-left: %dem;", INDENT);
584:
585: tag[0].key = ATTR_CLASS;
586: tag[0].val = "sec-body";
587: tag[1].key = ATTR_STYLE;
588: tag[1].val = buf;
589:
590: print_otag(h, TAG_DIV, 2, tag);
591: return(1);
592: }
593:
594:
595: /* ARGSUSED */
596: static int
597: mdoc_ss_pre(MDOC_ARGS)
598: {
599: struct htmlpair tag[2];
600: int i;
601: const struct mdoc_node *nn;
602:
603: i = 0;
604:
605: if (MDOC_BODY == n->type) {
606: tag[i].key = ATTR_CLASS;
607: tag[i++].val = "ssec-body";
608: if (n->parent->next && n->child) {
609: bufcat("margin-bottom: 1em;");
610: tag[i].key = ATTR_STYLE;
611: tag[i++].val = buf;
612: }
613: print_otag(h, TAG_DIV, i, tag);
614: return(1);
615: } else if (MDOC_BLOCK == n->type) {
616: tag[i].key = ATTR_CLASS;
617: tag[i++].val = "ssec-block";
618: if (n->prev) {
619: bufcat("margin-top: 1em;");
620: tag[i].key = ATTR_STYLE;
621: tag[i++].val = buf;
622: }
623: print_otag(h, TAG_DIV, i, tag);
624: return(1);
625: }
626:
627: buffmt("margin-left: -%dem;", INDENT - HALFINDENT);
628:
629: tag[0].key = ATTR_CLASS;
630: tag[0].val = "ssec-head";
631: tag[1].key = ATTR_STYLE;
632: tag[1].val = buf;
633:
634: print_otag(h, TAG_DIV, 2, tag);
635: print_otag(h, TAG_SPAN, 1, tag);
636:
637: bufinit();
638: for (nn = n->child; nn; nn = nn->next) {
639: bufcat(nn->string);
640: if (nn->next)
641: bufcat(" ");
642: }
643: tag[0].key = ATTR_NAME;
644: tag[0].val = buf;
645: print_otag(h, TAG_A, 1, tag);
646:
647: return(1);
648: }
649:
650:
651: /* ARGSUSED */
652: static int
653: mdoc_fl_pre(MDOC_ARGS)
654: {
655: struct htmlpair tag;
656:
657: tag.key = ATTR_CLASS;
658: tag.val = "flag";
659:
660: print_otag(h, TAG_SPAN, 1, &tag);
661: if (MDOC_Fl == n->tok) {
662: print_text(h, "\\-");
663: h->flags |= HTML_NOSPACE;
664: }
665: return(1);
666: }
667:
668:
669: /* ARGSUSED */
670: static int
671: mdoc_nd_pre(MDOC_ARGS)
672: {
673: struct htmlpair tag;
674:
675: if (MDOC_BODY != n->type)
676: return(1);
677:
678: /* XXX - this can contain block elements! */
679: print_text(h, "\\(em");
680: tag.key = ATTR_CLASS;
681: tag.val = "desc-body";
682: print_otag(h, TAG_SPAN, 1, &tag);
683: return(1);
684: }
685:
686:
687: /* ARGSUSED */
688: static int
689: mdoc_op_pre(MDOC_ARGS)
690: {
691: struct htmlpair tag;
692:
693: if (MDOC_BODY != n->type)
694: return(1);
695:
696: /* XXX - this can contain block elements! */
697: print_text(h, "\\(lB");
698: h->flags |= HTML_NOSPACE;
699: tag.key = ATTR_CLASS;
700: tag.val = "opt";
701: print_otag(h, TAG_SPAN, 1, &tag);
702: return(1);
703: }
704:
705:
706: /* ARGSUSED */
707: static void
708: mdoc_op_post(MDOC_ARGS)
709: {
710:
711: if (MDOC_BODY != n->type)
712: return;
713: h->flags |= HTML_NOSPACE;
714: print_text(h, "\\(rB");
715: }
716:
717:
718: static int
719: mdoc_nm_pre(MDOC_ARGS)
720: {
721: struct htmlpair tag;
722:
723: if ( ! (HTML_NEWLINE & h->flags))
724: if (SEC_SYNOPSIS == n->sec) {
725: tag.key = ATTR_STYLE;
726: tag.val = "clear: both;";
727: print_otag(h, TAG_BR, 1, &tag);
728: }
729:
730: tag.key = ATTR_CLASS;
731: tag.val = "name";
732:
733: print_otag(h, TAG_SPAN, 1, &tag);
734: if (NULL == n->child)
735: print_text(h, m->name);
736:
737: return(1);
738: }
739:
740:
741: /* ARGSUSED */
742: static int
743: mdoc_xr_pre(MDOC_ARGS)
744: {
745: struct htmlpair tag[2];
746: const char *name, *sec;
747: const struct mdoc_node *nn;
748:
749: nn = n->child;
750: name = nn && nn->string ? nn->string : "";
751: nn = nn ? nn->next : NULL;
752: sec = nn && nn->string ? nn->string : "";
753:
754: buffmt("%s%s%s.html", name, name && sec ? "." : "", sec);
755:
756: tag[0].key = ATTR_CLASS;
757: tag[0].val = "link-man";
758: tag[1].key = ATTR_HREF;
759: tag[1].val = buf;
760: print_otag(h, TAG_A, 2, tag);
761:
762: nn = n->child;
763: print_text(h, nn->string);
764: if (NULL == (nn = nn->next))
765: return(0);
766:
767: h->flags |= HTML_NOSPACE;
768: print_text(h, "(");
769: h->flags |= HTML_NOSPACE;
770: print_text(h, nn->string);
771: h->flags |= HTML_NOSPACE;
772: print_text(h, ")");
773:
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:
794: tag.key = ATTR_CLASS;
795: tag.val = "arg";
796:
797: print_otag(h, TAG_SPAN, 1, &tag);
798: return(1);
799: }
800:
801:
802: /* ARGSUSED */
803: static int
804: mdoc_xx_pre(MDOC_ARGS)
805: {
806: const char *pp;
807: struct htmlpair tag;
808:
809: switch (n->tok) {
810: case (MDOC_Bsx):
811: pp = "BSDI BSD/OS";
812: break;
813: case (MDOC_Dx):
814: pp = "DragonFlyBSD";
815: break;
816: case (MDOC_Fx):
817: pp = "FreeBSD";
818: break;
819: case (MDOC_Nx):
820: pp = "NetBSD";
821: break;
822: case (MDOC_Ox):
823: pp = "OpenBSD";
824: break;
825: case (MDOC_Ux):
826: pp = "UNIX";
827: break;
828: default:
829: return(1);
830: }
831:
832: tag.key = ATTR_CLASS;
833: tag.val = "unix";
834:
835: print_otag(h, TAG_SPAN, 1, &tag);
836: print_text(h, pp);
837: return(1);
838: }
839:
840:
841: /* ARGSUSED */
842: static int
1.4 kristaps 843: mdoc_bx_pre(MDOC_ARGS)
844: {
845: const struct mdoc_node *nn;
846: struct htmlpair tag;
847:
848: tag.key = ATTR_CLASS;
849: tag.val = "unix";
850:
851: print_otag(h, TAG_SPAN, 1, &tag);
852:
853: for (nn = n->child; nn; nn = nn->next)
854: print_mdoc_node(m, nn, h);
855:
856: if (n->child)
857: h->flags |= HTML_NOSPACE;
858:
859: print_text(h, "BSD");
860: return(0);
861: }
862:
863:
864: /* ARGSUSED */
865: static int
1.1 kristaps 866: mdoc_tbl_block_pre(MDOC_ARGS, int t, int w, int o, int c)
867: {
868: struct htmlpair tag;
869:
870: switch (t) {
871: case (MDOC_Column):
872: /* FALLTHROUGH */
873: case (MDOC_Item):
874: /* FALLTHROUGH */
875: case (MDOC_Ohang):
876: buffmt("margin-left: %dem; clear: both;", o);
877: break;
878: default:
879: buffmt("margin-left: %dem; clear: both;", w + o);
880: break;
881: }
882:
883: if ( ! c && MDOC_Column != t) {
884: if (n->prev && n->prev->body->child)
885: bufcat("padding-top: 1em;");
886: else if (NULL == n->prev)
887: bufcat("padding-top: 1em;");
888: }
889:
890: tag.key = ATTR_STYLE;
891: tag.val = buf;
892: print_otag(h, TAG_DIV, 1, &tag);
893: return(1);
894: }
895:
896:
897: /* ARGSUSED */
898: static int
899: mdoc_tbl_body_pre(MDOC_ARGS, int t, int w)
900: {
901:
902: print_otag(h, TAG_DIV, 0, NULL);
903: return(1);
904: }
905:
906:
907: /* ARGSUSED */
908: static int
909: mdoc_tbl_head_pre(MDOC_ARGS, int t, int w)
910: {
911: struct htmlpair tag;
912: struct ord *ord;
913: char nbuf[BUFSIZ];
914:
915: switch (t) {
916: case (MDOC_Item):
917: /* FALLTHROUGH */
918: case (MDOC_Ohang):
919: print_otag(h, TAG_DIV, 0, NULL);
920: break;
921: case (MDOC_Column):
922: buffmt("min-width: %dem;", w);
923: bufcat("clear: none;");
924: if (n->next && MDOC_HEAD == n->next->type)
925: bufcat("float: left;");
926: tag.key = ATTR_STYLE;
927: tag.val = buf;
928: print_otag(h, TAG_DIV, 1, &tag);
929: break;
930: default:
1.4 kristaps 931: buffmt("margin-left: -%dem; min-width: %dem;",
932: w, w ? w - 1 : 0);
1.1 kristaps 933: bufcat("clear: left;");
1.2 kristaps 934: if (n->next && n->next->child)
935: bufcat("float: left;");
1.1 kristaps 936: bufcat("padding-right: 1em;");
937: tag.key = ATTR_STYLE;
938: tag.val = buf;
939: print_otag(h, TAG_DIV, 1, &tag);
940: break;
941: }
942:
943: switch (t) {
944: case (MDOC_Diag):
945: tag.key = ATTR_CLASS;
946: tag.val = "diag";
947: print_otag(h, TAG_SPAN, 1, &tag);
948: break;
949: case (MDOC_Enum):
950: ord = SLIST_FIRST(&h->ords);
951: assert(ord);
952: nbuf[BUFSIZ - 1] = 0;
953: (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
954: print_text(h, nbuf);
955: return(0);
956: case (MDOC_Dash):
957: print_text(h, "\\(en");
958: return(0);
959: case (MDOC_Hyphen):
1.4 kristaps 960: print_text(h, "\\(hy");
1.1 kristaps 961: return(0);
962: case (MDOC_Bullet):
963: print_text(h, "\\(bu");
964: return(0);
965: default:
966: break;
967: }
968:
969: return(1);
970: }
971:
972:
973: static int
974: mdoc_tbl_pre(MDOC_ARGS, int type)
975: {
976: int i, w, o, c, wp;
977: const struct mdoc_node *bl, *nn;
978:
979: bl = n->parent->parent;
980: if (MDOC_BLOCK != n->type)
981: bl = bl->parent;
982:
983: /* FIXME: fmt_vspace() equivalent. */
984:
985: assert(bl->args);
986:
987: w = o = c = 0;
988: wp = -1;
989:
990: for (i = 0; i < (int)bl->args->argc; i++)
991: if (MDOC_Width == bl->args->argv[i].arg) {
992: assert(bl->args->argv[i].sz);
993: wp = i;
994: w = a2width(bl->args->argv[i].value[0]);
995: } else if (MDOC_Offset == bl->args->argv[i].arg) {
996: assert(bl->args->argv[i].sz);
997: o = a2offs(bl->args->argv[i].value[0]);
998: } else if (MDOC_Compact == bl->args->argv[i].arg)
999: c = 1;
1000:
1001: if (MDOC_HEAD == n->type && MDOC_Column == type) {
1002: nn = n->parent->child;
1003: assert(nn && MDOC_HEAD == nn->type);
1004: for (i = 0; nn && nn != n; nn = nn->next, i++)
1005: /* Counter... */ ;
1006: assert(nn);
1007: if (wp >= 0 && i < (int)bl->args[wp].argv->sz)
1008: w = a2width(bl->args->argv[wp].value[i]);
1009: }
1010:
1011: switch (type) {
1012: case (MDOC_Enum):
1013: /* FALLTHROUGH */
1014: case (MDOC_Dash):
1015: /* FALLTHROUGH */
1016: case (MDOC_Hyphen):
1017: /* FALLTHROUGH */
1018: case (MDOC_Bullet):
1019: if (w < 4)
1020: w = 4;
1021: break;
1022: case (MDOC_Inset):
1023: /* FALLTHROUGH */
1024: case (MDOC_Diag):
1025: w = 1;
1026: break;
1027: default:
1028: if (0 == w)
1029: w = 10;
1030: break;
1031: }
1032:
1033: switch (n->type) {
1034: case (MDOC_BLOCK):
1035: break;
1036: case (MDOC_HEAD):
1037: return(mdoc_tbl_head_pre(m, n, h, type, w));
1038: case (MDOC_BODY):
1039: return(mdoc_tbl_body_pre(m, n, h, type, w));
1040: default:
1041: abort();
1042: /* NOTREACHED */
1043: }
1044:
1045: return(mdoc_tbl_block_pre(m, n, h, type, w, o, c));
1046: }
1047:
1048:
1049: /* ARGSUSED */
1050: static int
1051: mdoc_bl_pre(MDOC_ARGS)
1052: {
1053: struct ord *ord;
1054:
1055: if (MDOC_BLOCK != n->type)
1056: return(1);
1057: if (MDOC_Enum != a2list(n))
1058: return(1);
1059:
1060: ord = malloc(sizeof(struct ord));
1061: if (NULL == ord)
1062: err(EXIT_FAILURE, "malloc");
1063: ord->cookie = n;
1064: ord->pos = 1;
1065: SLIST_INSERT_HEAD(&h->ords, ord, entry);
1066:
1067: return(1);
1068: }
1069:
1070:
1071: /* ARGSUSED */
1072: static void
1073: mdoc_bl_post(MDOC_ARGS)
1074: {
1075: struct ord *ord;
1076:
1077: if (MDOC_BLOCK != n->type)
1078: return;
1079: if (MDOC_Enum != a2list(n))
1080: return;
1081:
1082: ord = SLIST_FIRST(&h->ords);
1083: assert(ord);
1084: SLIST_REMOVE_HEAD(&h->ords, entry);
1085: free(ord);
1086: }
1087:
1088:
1089: static int
1090: mdoc_it_pre(MDOC_ARGS)
1091: {
1092: int type;
1093:
1094: if (MDOC_BLOCK == n->type)
1095: type = a2list(n->parent->parent);
1096: else
1097: type = a2list(n->parent->parent->parent);
1098:
1099: return(mdoc_tbl_pre(m, n, h, type));
1100: }
1101:
1102:
1103: /* ARGSUSED */
1104: static int
1105: mdoc_ex_pre(MDOC_ARGS)
1106: {
1107: const struct mdoc_node *nn;
1108: struct tag *t;
1109: struct htmlpair tag;
1110:
1111: print_text(h, "The");
1112:
1113: tag.key = ATTR_CLASS;
1114: tag.val = "utility";
1115:
1116: for (nn = n->child; nn; nn = nn->next) {
1117: t = print_otag(h, TAG_SPAN, 1, &tag);
1118: print_text(h, nn->string);
1119: print_tagq(h, t);
1120:
1121: h->flags |= HTML_NOSPACE;
1122:
1123: if (nn->next && NULL == nn->next->next)
1124: print_text(h, ", and");
1125: else if (nn->next)
1126: print_text(h, ",");
1127: else
1128: h->flags &= ~HTML_NOSPACE;
1129: }
1130:
1131: if (n->child->next)
1132: print_text(h, "utilities exit");
1133: else
1134: print_text(h, "utility exits");
1135:
1136: print_text(h, "0 on success, and >0 if an error occurs.");
1137: return(0);
1138: }
1139:
1140:
1141: /* ARGSUSED */
1142: static int
1143: mdoc_dq_pre(MDOC_ARGS)
1144: {
1145:
1146: if (MDOC_BODY != n->type)
1147: return(1);
1148: print_text(h, "\\(lq");
1149: h->flags |= HTML_NOSPACE;
1150: return(1);
1151: }
1152:
1153:
1154: /* ARGSUSED */
1155: static void
1156: mdoc_dq_post(MDOC_ARGS)
1157: {
1158:
1159: if (MDOC_BODY != n->type)
1160: return;
1161: h->flags |= HTML_NOSPACE;
1162: print_text(h, "\\(rq");
1163: }
1164:
1165:
1166: /* ARGSUSED */
1167: static int
1168: mdoc_pq_pre(MDOC_ARGS)
1169: {
1170:
1171: if (MDOC_BODY != n->type)
1172: return(1);
1173: print_text(h, "\\&(");
1174: h->flags |= HTML_NOSPACE;
1175: return(1);
1176: }
1177:
1178:
1179: /* ARGSUSED */
1180: static void
1181: mdoc_pq_post(MDOC_ARGS)
1182: {
1183:
1184: if (MDOC_BODY != n->type)
1185: return;
1186: print_text(h, ")");
1187: }
1188:
1189:
1190: /* ARGSUSED */
1191: static int
1192: mdoc_sq_pre(MDOC_ARGS)
1193: {
1194:
1195: if (MDOC_BODY != n->type)
1196: return(1);
1197: print_text(h, "\\(oq");
1198: h->flags |= HTML_NOSPACE;
1199: return(1);
1200: }
1201:
1202:
1203: /* ARGSUSED */
1204: static void
1205: mdoc_sq_post(MDOC_ARGS)
1206: {
1207:
1208: if (MDOC_BODY != n->type)
1209: return;
1210: h->flags |= HTML_NOSPACE;
1211: print_text(h, "\\(aq");
1212: }
1213:
1214:
1215: /* ARGSUSED */
1216: static int
1217: mdoc_em_pre(MDOC_ARGS)
1218: {
1219: struct htmlpair tag;
1220:
1221: tag.key = ATTR_CLASS;
1222: tag.val = "emph";
1223:
1224: print_otag(h, TAG_SPAN, 1, &tag);
1225: return(1);
1226: }
1227:
1228:
1229: /* ARGSUSED */
1230: static int
1231: mdoc_d1_pre(MDOC_ARGS)
1232: {
1233: struct htmlpair tag[2];
1234:
1235: if (MDOC_BLOCK != n->type)
1236: return(1);
1237:
1238: buffmt("margin-left: %dem;", INDENT);
1239:
1240: tag[0].key = ATTR_CLASS;
1.5 ! kristaps 1241: tag[0].val = "lit";
1.1 kristaps 1242: tag[1].key = ATTR_STYLE;
1243: tag[1].val = buf;
1244:
1245: print_otag(h, TAG_DIV, 2, tag);
1246: return(1);
1247: }
1248:
1249:
1250: /* ARGSUSED */
1251: static int
1252: mdoc_sx_pre(MDOC_ARGS)
1253: {
1254: struct htmlpair tag[2];
1255: const struct mdoc_node *nn;
1256:
1257: bufcat("#");
1258: for (nn = n->child; nn; nn = nn->next) {
1259: bufcat(nn->string);
1260: if (nn->next)
1261: bufcat(" ");
1262: }
1263:
1264: tag[0].key = ATTR_HREF;
1265: tag[0].val = buf;
1266: tag[1].key = ATTR_CLASS;
1267: tag[1].val = "link-sec";
1268:
1269: print_otag(h, TAG_A, 2, tag);
1270: return(1);
1271: }
1272:
1273:
1274: /* ARGSUSED */
1275: static int
1276: mdoc_aq_pre(MDOC_ARGS)
1277: {
1278:
1279: if (MDOC_BODY != n->type)
1280: return(1);
1281: print_text(h, "\\(la");
1282: h->flags |= HTML_NOSPACE;
1283: return(1);
1284: }
1285:
1286:
1287: /* ARGSUSED */
1288: static void
1289: mdoc_aq_post(MDOC_ARGS)
1290: {
1291:
1292: if (MDOC_BODY != n->type)
1293: return;
1294: h->flags |= HTML_NOSPACE;
1295: print_text(h, "\\(ra");
1296: }
1297:
1298:
1299: /* ARGSUSED */
1300: static int
1301: mdoc_bd_pre(MDOC_ARGS)
1302: {
1303: struct htmlpair tag[2];
1304: int t, c, o, i;
1305: const struct mdoc_node *bl;
1306:
1307: /* FIXME: fmt_vspace() shit. */
1308:
1309: if (MDOC_BLOCK == n->type)
1310: bl = n;
1311: else if (MDOC_HEAD == n->type)
1312: return(0);
1313: else
1314: bl = n->parent;
1315:
1316: t = o = c = 0;
1317:
1318: for (i = 0; i < (int)bl->args->argc; i++)
1319: switch (bl->args->argv[i].arg) {
1320: case (MDOC_Offset):
1321: assert(bl->args->argv[i].sz);
1322: o = a2offs (bl->args->argv[i].value[0]);
1323: break;
1324: case (MDOC_Compact):
1325: c = 1;
1326: break;
1327: case (MDOC_Ragged):
1328: /* FALLTHROUGH */
1329: case (MDOC_Filled):
1330: /* FALLTHROUGH */
1331: case (MDOC_Unfilled):
1332: /* FALLTHROUGH */
1333: case (MDOC_Literal):
1334: t = bl->args->argv[i].arg;
1335: break;
1336: }
1337:
1338: if (MDOC_BLOCK == n->type) {
1339: if (o)
1340: buffmt("margin-left: %dem;", o);
1341: bufcat("margin-top: 1em;");
1342: tag[0].key = ATTR_STYLE;
1343: tag[0].val = buf;
1344: print_otag(h, TAG_DIV, 1, tag);
1345: return(1);
1346: }
1347:
1348: switch (t) {
1349: case (MDOC_Unfilled):
1350: case (MDOC_Literal):
1351: break;
1352: default:
1353: return(1);
1354: }
1355:
1356: bufcat("white-space: pre;");
1357: tag[0].key = ATTR_STYLE;
1358: tag[0].val = buf;
1359: tag[1].key = ATTR_CLASS;
1.5 ! kristaps 1360: tag[1].val = "lit";
1.1 kristaps 1361:
1362: print_otag(h, TAG_DIV, 2, tag);
1363:
1364: for (n = n->child; n; n = n->next) {
1365: h->flags |= HTML_NOSPACE;
1366: print_mdoc_node(m, n, h);
1367: if (n->next)
1368: print_text(h, "\n");
1369: }
1370:
1371: return(0);
1372: }
1373:
1374:
1375: /* ARGSUSED */
1376: static int
1377: mdoc_pa_pre(MDOC_ARGS)
1378: {
1379: struct htmlpair tag;
1380:
1381: tag.key = ATTR_CLASS;
1382: tag.val = "file";
1383:
1384: print_otag(h, TAG_SPAN, 1, &tag);
1385: return(1);
1386: }
1387:
1388:
1389: /* ARGSUSED */
1390: static int
1391: mdoc_ad_pre(MDOC_ARGS)
1392: {
1393: struct htmlpair tag;
1394:
1395: tag.key = ATTR_CLASS;
1396: tag.val = "addr";
1397: print_otag(h, TAG_SPAN, 1, &tag);
1398: return(1);
1399: }
1400:
1401:
1402: /* ARGSUSED */
1403: static int
1404: mdoc_an_pre(MDOC_ARGS)
1405: {
1406: struct htmlpair tag;
1407:
1408: tag.key = ATTR_CLASS;
1409: tag.val = "author";
1410: print_otag(h, TAG_SPAN, 1, &tag);
1411: return(1);
1412: }
1413:
1414:
1415: /* ARGSUSED */
1416: static int
1417: mdoc_cd_pre(MDOC_ARGS)
1418: {
1419: struct htmlpair tag;
1420:
1421: tag.key = ATTR_CLASS;
1422: tag.val = "config";
1423: print_otag(h, TAG_SPAN, 1, &tag);
1424: return(1);
1425: }
1426:
1427:
1428: /* ARGSUSED */
1429: static int
1430: mdoc_dv_pre(MDOC_ARGS)
1431: {
1432: struct htmlpair tag;
1433:
1434: tag.key = ATTR_CLASS;
1435: tag.val = "define";
1436: print_otag(h, TAG_SPAN, 1, &tag);
1437: return(1);
1438: }
1439:
1440:
1441: /* ARGSUSED */
1442: static int
1443: mdoc_ev_pre(MDOC_ARGS)
1444: {
1445: struct htmlpair tag;
1446:
1447: tag.key = ATTR_CLASS;
1448: tag.val = "env";
1449: print_otag(h, TAG_SPAN, 1, &tag);
1450: return(1);
1451: }
1452:
1453:
1454: /* ARGSUSED */
1455: static int
1456: mdoc_er_pre(MDOC_ARGS)
1457: {
1458: struct htmlpair tag;
1459:
1460: tag.key = ATTR_CLASS;
1461: tag.val = "errno";
1462: print_otag(h, TAG_SPAN, 1, &tag);
1463: return(1);
1464: }
1465:
1466:
1467: /* ARGSUSED */
1468: static int
1469: mdoc_fa_pre(MDOC_ARGS)
1470: {
1471: const struct mdoc_node *nn;
1472: struct htmlpair tag;
1473: struct tag *t;
1474:
1475: tag.key = ATTR_CLASS;
1476: tag.val = "farg";
1477:
1478: if (n->parent->tok != MDOC_Fo) {
1479: print_otag(h, TAG_SPAN, 1, &tag);
1480: return(1);
1481: }
1482:
1483: for (nn = n->child; nn; nn = nn->next) {
1484: t = print_otag(h, TAG_SPAN, 1, &tag);
1485: print_text(h, nn->string);
1486: print_tagq(h, t);
1487: if (nn->next)
1488: print_text(h, ",");
1489: }
1490:
1491: if (n->child && n->next && n->next->tok == MDOC_Fa)
1492: print_text(h, ",");
1493:
1494: return(0);
1495: }
1496:
1497:
1498: /* ARGSUSED */
1499: static int
1500: mdoc_fd_pre(MDOC_ARGS)
1501: {
1502: struct htmlpair tag;
1503:
1504: if (SEC_SYNOPSIS == n->sec) {
1505: if (n->next && MDOC_Fd != n->next->tok) {
1506: tag.key = ATTR_STYLE;
1507: tag.val = "margin-bottom: 1em;";
1508: print_otag(h, TAG_DIV, 1, &tag);
1509: } else
1510: print_otag(h, TAG_DIV, 0, NULL);
1511: }
1512:
1513: tag.key = ATTR_CLASS;
1514: tag.val = "macro";
1515: print_otag(h, TAG_SPAN, 1, &tag);
1516: return(1);
1517: }
1518:
1519:
1520: /* ARGSUSED */
1521: static int
1522: mdoc_vt_pre(MDOC_ARGS)
1523: {
1524: struct htmlpair tag;
1525:
1526: if (SEC_SYNOPSIS == n->sec) {
1527: if (n->next && MDOC_Vt != n->next->tok) {
1528: tag.key = ATTR_STYLE;
1529: tag.val = "margin-bottom: 1em;";
1530: print_otag(h, TAG_DIV, 1, &tag);
1531: } else
1532: print_otag(h, TAG_DIV, 0, NULL);
1533: }
1534:
1535: tag.key = ATTR_CLASS;
1536: tag.val = "type";
1537: print_otag(h, TAG_SPAN, 1, &tag);
1538: return(1);
1539: }
1540:
1.2 kristaps 1541:
1.1 kristaps 1542: /* ARGSUSED */
1543: static int
1544: mdoc_ft_pre(MDOC_ARGS)
1545: {
1546: struct htmlpair tag;
1547:
1548: if (SEC_SYNOPSIS == n->sec) {
1549: if (n->prev && MDOC_Fo == n->prev->tok) {
1550: tag.key = ATTR_STYLE;
1.4 kristaps 1551: tag.val = "margin-top: 1em;";
1.1 kristaps 1552: print_otag(h, TAG_DIV, 1, &tag);
1553: } else
1554: print_otag(h, TAG_DIV, 0, NULL);
1555: }
1556:
1557: tag.key = ATTR_CLASS;
1558: tag.val = "type";
1559: print_otag(h, TAG_SPAN, 1, &tag);
1560: return(1);
1561: }
1562:
1563:
1564: /* ARGSUSED */
1565: static int
1566: mdoc_fn_pre(MDOC_ARGS)
1567: {
1568: struct tag *t;
1569: struct htmlpair tag;
1570: const struct mdoc_node *nn;
1571:
1572: if (SEC_SYNOPSIS == n->sec) {
1573: if (n->next) {
1574: tag.key = ATTR_STYLE;
1575: tag.val = "margin-bottom: 1em";
1576: print_otag(h, TAG_DIV, 1, &tag);
1577: } else
1578: print_otag(h, TAG_DIV, 0, NULL);
1579: }
1580:
1581: tag.key = ATTR_CLASS;
1582: tag.val = "type";
1583:
1.4 kristaps 1584: /* FIXME: can be "type funcname" "type varname"... */
1585:
1.1 kristaps 1586: t = print_otag(h, TAG_SPAN, 1, &tag);
1587: print_text(h, n->child->string);
1588: print_tagq(h, t);
1589:
1590: h->flags |= HTML_NOSPACE;
1591: print_text(h, "(");
1592:
1593: for (nn = n->child->next; nn; nn = nn->next) {
1594: tag.key = ATTR_CLASS;
1595: tag.val = "farg";
1596: t = print_otag(h, TAG_SPAN, 1, &tag);
1597: print_text(h, nn->string);
1598: print_tagq(h, t);
1599: if (nn->next)
1600: print_text(h, ",");
1601: }
1602:
1603: print_text(h, ")");
1604:
1605: if (SEC_SYNOPSIS == n->sec)
1606: print_text(h, ";");
1607:
1608: return(0);
1609: }
1610:
1611:
1612: /* ARGSUSED */
1613: static int
1614: mdoc_sp_pre(MDOC_ARGS)
1615: {
1616: int len;
1617: struct htmlpair tag;
1618:
1619: switch (n->tok) {
1620: case (MDOC_sp):
1621: len = n->child ? atoi(n->child->string) : 1;
1622: break;
1623: case (MDOC_br):
1624: len = 0;
1625: break;
1626: default:
1627: len = 1;
1628: break;
1629: }
1630:
1631: buffmt("height: %dem", len);
1632: tag.key = ATTR_STYLE;
1633: tag.val = buf;
1634: print_otag(h, TAG_DIV, 1, &tag);
1635: return(1);
1636:
1637: }
1.2 kristaps 1638:
1639:
1640: /* ARGSUSED */
1641: static int
1642: mdoc_brq_pre(MDOC_ARGS)
1643: {
1644:
1645: if (MDOC_BODY != n->type)
1646: return(1);
1647: print_text(h, "\\(lC");
1648: h->flags |= HTML_NOSPACE;
1649: return(1);
1650: }
1651:
1652:
1653: /* ARGSUSED */
1654: static void
1655: mdoc_brq_post(MDOC_ARGS)
1656: {
1657:
1658: if (MDOC_BODY != n->type)
1659: return;
1660: h->flags |= HTML_NOSPACE;
1661: print_text(h, "\\(rC");
1662: }
1663:
1664:
1665: /* ARGSUSED */
1666: static int
1667: mdoc_lk_pre(MDOC_ARGS)
1668: {
1669: const struct mdoc_node *nn;
1670: struct htmlpair tag[2];
1671:
1672: nn = n->child;
1673:
1674: tag[0].key = ATTR_CLASS;
1675: tag[0].val = "link-ext";
1676: tag[1].key = ATTR_HREF;
1677: tag[1].val = nn->string;
1678:
1679: print_otag(h, TAG_A, 2, tag);
1680:
1681: if (NULL == nn->next)
1682: return(1);
1683:
1684: for (nn = nn->next; nn; nn = nn->next)
1685: print_text(h, nn->string);
1686:
1687: return(0);
1688: }
1689:
1690:
1691: /* ARGSUSED */
1692: static int
1693: mdoc_mt_pre(MDOC_ARGS)
1694: {
1695: struct htmlpair tag[2];
1696: struct tag *t;
1697: const struct mdoc_node *nn;
1698:
1699: tag[0].key = ATTR_CLASS;
1700: tag[0].val = "link-mail";
1701:
1702: for (nn = n->child; nn; nn = nn->next) {
1703: bufinit();
1704: bufcat("mailto:");
1705: bufcat(nn->string);
1706:
1707: tag[1].key = ATTR_HREF;
1708: tag[1].val = buf;
1709:
1710: t = print_otag(h, TAG_A, 2, tag);
1711: print_text(h, nn->string);
1712: print_tagq(h, t);
1713: }
1714:
1715: return(0);
1716: }
1.4 kristaps 1717:
1718:
1719: /* ARGSUSED */
1720: static int
1721: mdoc_fo_pre(MDOC_ARGS)
1722: {
1723: struct htmlpair tag;
1724:
1725: if (MDOC_BODY == n->type) {
1726: h->flags |= HTML_NOSPACE;
1727: print_text(h, "(");
1728: h->flags |= HTML_NOSPACE;
1729: return(1);
1730: } else if (MDOC_BLOCK == n->type)
1731: return(1);
1732:
1733: tag.key = ATTR_CLASS;
1734: tag.val = "fname";
1735: print_otag(h, TAG_SPAN, 1, &tag);
1736: return(1);
1737: }
1738:
1739:
1740: /* ARGSUSED */
1741: static void
1742: mdoc_fo_post(MDOC_ARGS)
1743: {
1744: if (MDOC_BODY != n->type)
1745: return;
1746: h->flags |= HTML_NOSPACE;
1747: print_text(h, ")");
1748: h->flags |= HTML_NOSPACE;
1749: print_text(h, ";");
1750: }
1751:
1752:
1753: /* ARGSUSED */
1754: static int
1755: mdoc_in_pre(MDOC_ARGS)
1756: {
1757: const struct mdoc_node *nn;
1758: struct htmlpair tag;
1759:
1760: if (SEC_SYNOPSIS == n->sec) {
1761: if (n->next && MDOC_In != n->next->tok) {
1762: tag.key = ATTR_STYLE;
1763: tag.val = "margin-bottom: 1em;";
1764: print_otag(h, TAG_DIV, 1, &tag);
1765: } else
1766: print_otag(h, TAG_DIV, 0, NULL);
1767: }
1768:
1769: tag.key = ATTR_CLASS;
1770: tag.val = "includes";
1771:
1772: print_otag(h, TAG_SPAN, 1, &tag);
1773:
1774: if (SEC_SYNOPSIS == n->sec)
1775: print_text(h, "#include");
1776:
1777: print_text(h, "<");
1778: h->flags |= HTML_NOSPACE;
1779:
1780: /* XXX -- see warning in termp_in_post(). */
1781:
1782: for (nn = n->child; nn; nn = nn->next)
1783: print_mdoc_node(m, nn, h);
1784:
1785: h->flags |= HTML_NOSPACE;
1786: print_text(h, ">");
1787:
1788: return(0);
1789: }
1790:
1791:
1792: /* ARGSUSED */
1793: static int
1794: mdoc_ic_pre(MDOC_ARGS)
1795: {
1796: struct htmlpair tag;
1797:
1798: tag.key = ATTR_CLASS;
1799: tag.val = "cmd";
1800:
1801: print_otag(h, TAG_SPAN, 1, &tag);
1802: return(1);
1803: }
1804:
1805:
1806: /* ARGSUSED */
1807: static int
1808: mdoc_rv_pre(MDOC_ARGS)
1809: {
1810: const struct mdoc_node *nn;
1811: struct htmlpair tag;
1812: struct tag *t;
1813:
1814: print_otag(h, TAG_DIV, 0, NULL);
1815:
1816: print_text(h, "The");
1817:
1818: for (nn = n->child; nn; nn = nn->next) {
1819: tag.key = ATTR_CLASS;
1820: tag.val = "fname";
1821: t = print_otag(h, TAG_SPAN, 1, &tag);
1822: print_text(h, nn->string);
1823: print_tagq(h, t);
1824:
1825: h->flags |= HTML_NOSPACE;
1826: if (nn->next && NULL == nn->next->next)
1827: print_text(h, "(), and");
1828: else if (nn->next)
1829: print_text(h, "(),");
1830: else
1831: print_text(h, "()");
1832: }
1833:
1834: if (n->child->next)
1835: print_text(h, "functions return");
1836: else
1837: print_text(h, "function returns");
1838:
1839: print_text(h, "the value 0 if successful; otherwise the value "
1840: "-1 is returned and the global variable");
1841:
1842: tag.key = ATTR_CLASS;
1843: tag.val = "var";
1844: t = print_otag(h, TAG_SPAN, 1, &tag);
1845: print_text(h, "errno");
1846: print_tagq(h, t);
1847: print_text(h, "is set to indicate the error.");
1848: return(0);
1849: }
1850:
1851:
1852: /* ARGSUSED */
1853: static int
1854: mdoc_va_pre(MDOC_ARGS)
1855: {
1856: struct htmlpair tag;
1857:
1858: tag.key = ATTR_CLASS;
1859: tag.val = "var";
1860: print_otag(h, TAG_SPAN, 1, &tag);
1861: return(1);
1862: }
1863:
1864:
1865: /* ARGSUSED */
1866: static int
1867: mdoc_bq_pre(MDOC_ARGS)
1868: {
1869:
1870: if (MDOC_BODY != n->type)
1871: return(1);
1872: print_text(h, "\\(lB");
1873: h->flags |= HTML_NOSPACE;
1874: return(1);
1875: }
1876:
1877:
1878: /* ARGSUSED */
1879: static void
1880: mdoc_bq_post(MDOC_ARGS)
1881: {
1882:
1883: if (MDOC_BODY != n->type)
1884: return;
1885: h->flags |= HTML_NOSPACE;
1886: print_text(h, "\\(rB");
1887: }
1.5 ! kristaps 1888:
! 1889:
! 1890: /* ARGSUSED */
! 1891: static int
! 1892: mdoc_ap_pre(MDOC_ARGS)
! 1893: {
! 1894:
! 1895: h->flags |= HTML_NOSPACE;
! 1896: print_text(h, "\\(aq");
! 1897: h->flags |= HTML_NOSPACE;
! 1898: return(1);
! 1899: }
! 1900:
! 1901:
! 1902: /* ARGSUSED */
! 1903: static int
! 1904: mdoc_bf_pre(MDOC_ARGS)
! 1905: {
! 1906: int i;
! 1907: struct htmlpair tag[2];
! 1908:
! 1909: if (MDOC_HEAD == n->type)
! 1910: return(0);
! 1911: else if (MDOC_BLOCK != n->type)
! 1912: return(1);
! 1913:
! 1914: tag[0].key = ATTR_CLASS;
! 1915: tag[0].val = NULL;
! 1916:
! 1917: if (n->head->child) {
! 1918: if ( ! strcmp("Em", n->head->child->string))
! 1919: tag[0].val = "emph";
! 1920: else if ( ! strcmp("Sy", n->head->child->string))
! 1921: tag[0].val = "symb";
! 1922: else if ( ! strcmp("Li", n->head->child->string))
! 1923: tag[0].val = "lit";
! 1924: } else {
! 1925: assert(n->args);
! 1926: for (i = 0; i < (int)n->args->argc; i++)
! 1927: switch (n->args->argv[i].arg) {
! 1928: case (MDOC_Symbolic):
! 1929: tag[0].val = "symb";
! 1930: break;
! 1931: case (MDOC_Literal):
! 1932: tag[0].val = "lit";
! 1933: break;
! 1934: case (MDOC_Emphasis):
! 1935: tag[0].val = "emph";
! 1936: break;
! 1937: default:
! 1938: break;
! 1939: }
! 1940: }
! 1941:
! 1942: /* FIXME: div's have spaces stripped--we want them. */
! 1943:
! 1944: assert(tag[0].val);
! 1945: tag[1].key = ATTR_STYLE;
! 1946: tag[1].val = "display: inline; margin-right: 1em;";
! 1947: print_otag(h, TAG_DIV, 2, tag);
! 1948: return(1);
! 1949: }
! 1950:
! 1951:
! 1952: /* ARGSUSED */
! 1953: static int
! 1954: mdoc_ms_pre(MDOC_ARGS)
! 1955: {
! 1956: struct htmlpair tag;
! 1957:
! 1958: tag.key = ATTR_CLASS;
! 1959: tag.val = "symb";
! 1960: print_otag(h, TAG_SPAN, 1, &tag);
! 1961: return(1);
! 1962: }
! 1963:
! 1964:
! 1965: /* ARGSUSED */
! 1966: static int
! 1967: mdoc_pf_pre(MDOC_ARGS)
! 1968: {
! 1969:
! 1970: h->flags |= HTML_IGNDELIM;
! 1971: return(1);
! 1972: }
! 1973:
! 1974:
! 1975: /* ARGSUSED */
! 1976: static void
! 1977: mdoc_pf_post(MDOC_ARGS)
! 1978: {
! 1979:
! 1980: h->flags &= ~HTML_IGNDELIM;
! 1981: h->flags |= HTML_NOSPACE;
! 1982: }
! 1983:
! 1984:
! 1985: /* ARGSUSED */
! 1986: static int
! 1987: mdoc_rs_pre(MDOC_ARGS)
! 1988: {
! 1989: struct htmlpair tag[2];
! 1990: int i;
! 1991:
! 1992: if (MDOC_BLOCK != n->type)
! 1993: return(1);
! 1994:
! 1995: tag[i = 0].key = ATTR_CLASS;
! 1996: tag[i++].val = "ref";
! 1997:
! 1998: if (n->prev && SEC_SYNOPSIS == n->sec) {
! 1999: tag[i].key = ATTR_STYLE;
! 2000: tag[i++].val = "margin-top: 1em;";
! 2001: } else if (SEC_SYNOPSIS != n->sec) {
! 2002: tag[i].key = ATTR_STYLE;
! 2003: tag[i++].val = "display: inline; margin-right: 1em";
! 2004: }
! 2005:
! 2006: /* FIXME: div's have spaces stripped--we want them. */
! 2007:
! 2008: print_otag(h, TAG_DIV, i, tag);
! 2009: return(1);
! 2010: }
CVSweb