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