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