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