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