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