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